'use client';

/**
 * Theme A.5/A.6 — 2FA challenge modal.
 *
 * Appears after /api/auth/login returns `needs2FA: true`. Owns the
 * pendingToken and the TOTP/backup-code input. On success, hands a
 * post-2fa sessionToken back to the parent for signIn() handoff.
 *
 * No state outside what's required for one challenge — the parent
 * mounts/unmounts the modal as needed.
 */

import { useState, useEffect, useRef } from 'react';
import { ShieldCheck, X, KeyRound } from 'lucide-react';
import { Button, IconButton } from '@/components/ui';

interface TwoFactorModalProps {
    pendingToken: string;
    onSuccess: (sessionToken: string) => void;
    onCancel: () => void;
}

export function TwoFactorModal({ pendingToken, onSuccess, onCancel }: TwoFactorModalProps) {
    const [code, setCode] = useState('');
    const [usingBackup, setUsingBackup] = useState(false);
    const [submitting, setSubmitting] = useState(false);
    const [error, setError] = useState('');
    const inputRef = useRef<HTMLInputElement>(null);

    useEffect(() => {
        // Autofocus the input on mount and whenever the input mode toggles
        // so the user can type immediately. requestAnimationFrame ensures
        // the DOM is painted before we focus.
        const id = requestAnimationFrame(() => inputRef.current?.focus());
        return () => cancelAnimationFrame(id);
    }, [usingBackup]);

    async function handleSubmit(e: React.FormEvent) {
        e.preventDefault();
        if (!code.trim()) return;
        setSubmitting(true);
        setError('');
        try {
            const res = await fetch('/api/auth/2fa-challenge', {
                method: 'POST',
                headers: { 'content-type': 'application/json' },
                body: JSON.stringify({ pendingToken, code: code.trim() }),
            });
            const data = await res.json();
            if (!res.ok) {
                setError(data?.message || data?.error || 'Verification failed');
                setSubmitting(false);
                setCode('');
                return;
            }
            onSuccess(data.sessionToken);
        } catch (err) {
            setError(err instanceof Error ? err.message : 'Network error');
            setSubmitting(false);
        }
    }

    const placeholder = usingBackup ? 'BACK-UP01' : '123456';
    const label = usingBackup ? 'Backup code' : 'Authenticator code';
    const helpText = usingBackup
        ? 'Enter one of the backup codes you saved when enabling 2FA. Each can be used only once.'
        : 'Enter the 6-digit code from your Authenticator app.';

    return (
        <div
            className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4"
            role="dialog"
            aria-modal="true"
            aria-labelledby="twofa-modal-title"
        >
            <div className="w-full max-w-sm bg-slate-900 rounded-2xl shadow-2xl shadow-black/40 p-6 border border-slate-700">
                <div className="flex items-start justify-between mb-4">
                    <div className="flex items-center gap-2">
                        <ShieldCheck className="size-5 text-amber-400" />
                        <h2 id="twofa-modal-title" className="text-base font-bold text-white">
                            Two-factor authentication
                        </h2>
                    </div>
                    <IconButton
                        label="Cancel sign-in"
                        variant="ghost"
                        size="md"
                        onClick={onCancel}
                        className="text-slate-400 hover:text-white"
                    >
                        <X className="size-5" />
                    </IconButton>
                </div>

                <p className="text-xs text-slate-400 mb-4">{helpText}</p>

                <form onSubmit={handleSubmit} className="space-y-3">
                    <div>
                        <label htmlFor="twofa-code" className="block text-xs font-bold text-slate-300 mb-1">
                            {label}
                        </label>
                        <input
                            ref={inputRef}
                            id="twofa-code"
                            name="code"
                            type={usingBackup ? 'text' : 'tel'}
                            inputMode={usingBackup ? 'text' : 'numeric'}
                            autoComplete={usingBackup ? 'off' : 'one-time-code'}
                            maxLength={usingBackup ? 14 : 6}
                            value={code}
                            onChange={(e) => setCode(e.target.value)}
                            placeholder={placeholder}
                            className="w-full h-10 px-3 rounded-lg bg-slate-800 border border-slate-700 focus:outline-none focus:ring-2 focus:ring-amber-500/30 focus:border-amber-500 transition-all text-sm text-white placeholder:text-slate-500 tracking-widest"
                        />
                    </div>

                    {error && (
                        <div className="text-xs text-red-400 bg-red-900/20 border border-red-900/40 rounded-lg px-3 py-2">
                            {error}
                        </div>
                    )}

                    <Button
                        type="submit"
                        variant="primary"
                        size="md"
                        disabled={submitting || code.trim().length === 0}
                        className="w-full bg-amber-500 hover:bg-amber-400 text-white font-bold shadow-lg shadow-amber-500/20 active:scale-[0.98] text-sm"
                    >
                        {submitting ? 'Verifying...' : 'Verify'}
                    </Button>
                </form>

                <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                        setUsingBackup(!usingBackup);
                        setCode('');
                        setError('');
                    }}
                    className="mt-4 w-full text-xs text-slate-400 hover:text-amber-400"
                >
                    <KeyRound className="size-3.5" />
                    {usingBackup ? 'Use authenticator code instead' : 'Use a backup code instead'}
                </Button>
            </div>
        </div>
    );
}
