import { useState, type FormEvent } from 'react';
import { useNavigate } from 'react-router-dom';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Logo } from '@/components/brand/Logo';
import { Button } from '@/components/ui/Button';
import { Pill } from '@/components/ui/Pill';
import { ApiClientError } from '@/lib/api';
import { login } from '@/session/sessionApi';
import { SESSION_QUERY_KEY } from '@/session/useSession';

type Mode = 'rt' | 'soc';

/**
 * Login screen — two distinct paths.
 *
 * Sprint 1 wires the RT operator path against POST /api/v1/auth/login.
 * The SOC analyst path stays visible (so the masthead doesn't change) but
 * is deferred to sprint 2 when the backend exposes /auth/soc/session.
 *
 * On success the server sets an HttpOnly session cookie; the response body
 * is the User. We seed the TanStack Query cache directly so the next render
 * pass already has the user, then navigate to /engagements (the post-login
 * landing for RT). No localStorage, no client-side credential persistence.
 *
 * Error policy: we never echo the backend message verbatim (could leak
 * "user not found" vs "wrong password"). 401 → generic "Identifiants
 * invalides". 4xx/5xx other → generic "Connexion impossible".
 */
export function LoginPage() {
  const [mode, setMode] = useState<Mode>('rt');
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [errorMsg, setErrorMsg] = useState<string | null>(null);

  const navigate = useNavigate();
  const queryClient = useQueryClient();

  const loginMutation = useMutation({
    mutationFn: login,
    onSuccess: (user) => {
      queryClient.setQueryData(SESSION_QUERY_KEY, user);
      setErrorMsg(null);
      void navigate('/engagements', { replace: true });
    },
    onError: (err) => {
      if (err instanceof ApiClientError && err.status === 401) {
        setErrorMsg('Identifiants invalides.');
      } else {
        setErrorMsg('Connexion impossible. Réessayez dans un instant.');
      }
    },
  });

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    if (mode !== 'rt') return;
    if (!username || !password) {
      setErrorMsg('Nom d’utilisateur et mot de passe requis.');
      return;
    }
    loginMutation.mutate({ username, password });
  };

  return (
    <div className="min-h-screen flex" style={{ backgroundColor: 'var(--surface-0)' }}>
      <aside
        className="hidden lg:flex flex-col justify-between w-[420px] border-r p-10"
        style={{
          borderColor: 'var(--line-default)',
          backgroundColor: 'var(--surface-1)',
        }}
      >
        <div className="space-y-10">
          <Logo build="0.1.0" />

          <div className="space-y-4">
            <div className="label-system">// Mission brief</div>
            <p className="text-fg-default" style={{ fontSize: '15px', lineHeight: 1.55 }}>
              Internal Breach &amp; Attack Simulation platform.
              <br />
              <span className="text-fg-muted">
                Replays red-team TTPs against client infrastructure in white-glove coordination
                with the SOC. Outputs a measurable MITRE ATT&amp;CK coverage report per
                engagement.
              </span>
            </p>
          </div>

          <div className="space-y-3 font-mono tabular text-fg-faint" style={{ fontSize: '11px' }}>
            <div className="flex gap-3">
              <span className="w-24 text-fg-subtle">deploy</span>
              <span>RT infra · Caddy + TLS · OPSEC handled by RP</span>
            </div>
            <div className="flex gap-3">
              <span className="w-24 text-fg-subtle">auth</span>
              <span>local user/password v1 · OIDC v2</span>
            </div>
          </div>
        </div>

        <div className="space-y-2 font-mono text-fg-faint" style={{ fontSize: '10px' }}>
          <div>// Mimic is for authorized engagements only.</div>
          <div>// Access is logged, audited, and reviewed weekly.</div>
        </div>
      </aside>

      <div className="flex-1 flex items-center justify-center px-8 py-16">
        <div className="w-full max-w-[420px]">
          <div className="flex items-center gap-1 mb-6" role="tablist" aria-label="Login mode">
            <ModeTab
              active={mode === 'rt'}
              onClick={() => setMode('rt')}
              tone="rt"
              label="RT — operator"
              hint="username + password"
            />
            <ModeTab
              active={mode === 'soc'}
              onClick={() => setMode('soc')}
              tone="soc"
              label="SOC — analyst"
              hint="session token (sprint 2)"
            />
          </div>

          <form
            onSubmit={handleSubmit}
            className="p-6 corner-mark"
            style={{
              backgroundColor: 'var(--surface-2)',
              border: '1px solid var(--line-default)',
              borderRadius: 'var(--radius-md)',
              boxShadow: 'var(--shadow-panel)',
            }}
          >
            <div className="flex items-center justify-between mb-4">
              <h1
                className="font-display text-fg-default"
                style={{ fontSize: '15px', letterSpacing: '0.05em' }}
              >
                {mode === 'rt' ? 'Operator sign-in' : 'SOC session'}
              </h1>
              <Pill tone={mode}>{mode === 'rt' ? 'RT' : 'SOC'}</Pill>
            </div>

            {mode === 'rt' ? (
              <div className="space-y-4">
                <Field
                  label="Username"
                  name="username"
                  autoComplete="username"
                  value={username}
                  onChange={setUsername}
                  disabled={loginMutation.isPending}
                />
                <Field
                  label="Password"
                  name="password"
                  type="password"
                  autoComplete="current-password"
                  value={password}
                  onChange={setPassword}
                  disabled={loginMutation.isPending}
                />
              </div>
            ) : (
              <SocPlaceholder />
            )}

            {errorMsg && mode === 'rt' && (
              <p
                role="alert"
                className="mt-4 label-system"
                style={{
                  color: 'var(--state-failed)',
                  border: '1px solid var(--state-failed)',
                  padding: '6px 10px',
                  borderRadius: 'var(--radius-sm)',
                }}
              >
                {errorMsg}
              </p>
            )}

            <div className="mt-6 flex items-center justify-between gap-3">
              <p className="label-system text-fg-faint">
                {mode === 'rt' ? 'OIDC Keycloak — v2' : 'Token delivered out-of-band'}
              </p>
              <Button
                type="submit"
                variant="primary"
                disabled={mode !== 'rt' || loginMutation.isPending}
              >
                {loginMutation.isPending ? 'Authenticating …' : 'Enter Mimic →'}
              </Button>
            </div>
          </form>

          <p
            className="mt-6 font-mono text-fg-faint text-center"
            style={{ fontSize: '10.5px', letterSpacing: '0.08em' }}
          >
            mimic.rt.local · session cookie HttpOnly · audit log live
          </p>
        </div>
      </div>
    </div>
  );
}

interface ModeTabProps {
  active: boolean;
  onClick: () => void;
  tone: 'rt' | 'soc';
  label: string;
  hint: string;
}

function ModeTab({ active, onClick, tone, label, hint }: ModeTabProps) {
  return (
    <button
      type="button"
      role="tab"
      aria-selected={active}
      onClick={onClick}
      className="flex-1 text-left px-3 py-2 transition-colors"
      style={{
        backgroundColor: active ? 'var(--surface-2)' : 'transparent',
        border: '1px solid',
        borderColor: active
          ? tone === 'rt'
            ? 'var(--accent-rt-muted)'
            : 'var(--accent-soc-muted)'
          : 'var(--line-default)',
        borderRadius: 'var(--radius-sm)',
        boxShadow: active ? 'var(--shadow-panel)' : 'none',
      }}
    >
      <div
        className="label-system"
        style={{
          color: active
            ? tone === 'rt'
              ? 'var(--accent-rt)'
              : 'var(--accent-soc)'
            : 'var(--fg-subtle)',
        }}
      >
        {label}
      </div>
      <div className="font-mono text-fg-faint mt-1" style={{ fontSize: '10px' }}>
        {hint}
      </div>
    </button>
  );
}

function SocPlaceholder() {
  return (
    <p
      className="font-mono text-fg-faint"
      style={{ fontSize: '11px', lineHeight: 1.55 }}
    >
      SOC session sign-in lands in sprint 2 once the backend exposes
      <br />
      <code style={{ fontSize: '10.5px' }}>POST /api/v1/auth/soc/session</code>.
      <br />
      For now, use the RT path with a local account.
    </p>
  );
}

interface FieldProps {
  label: string;
  name: string;
  type?: string;
  autoComplete?: string;
  value: string;
  onChange: (next: string) => void;
  disabled?: boolean;
}

function Field({ label, name, type = 'text', autoComplete, value, onChange, disabled }: FieldProps) {
  return (
    <div>
      <label htmlFor={name} className="block label-system mb-1.5">
        {label}
      </label>
      <input
        id={name}
        name={name}
        type={type}
        autoComplete={autoComplete}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        required
        className="font-sans"
        style={{
          width: '100%',
          height: 32,
          padding: '0 10px',
          backgroundColor: 'var(--surface-inset)',
          color: 'var(--fg-default)',
          border: '1px solid var(--line-strong)',
          borderRadius: 'var(--radius-sm)',
          fontSize: 12.5,
        }}
      />
    </div>
  );
}
