"use client";

import { useEffect, useState } from 'react';
import api from '../../lib/api';

type AuthProvider = {
    name: 'local' | 'ldap' | 'oidc' | 'saml';
    credentials: boolean;     // shows username/password form
    redirect: boolean;        // shows redirect button
    display_name: string;
    login_url?: string | null;
};

type Stage = 'credentials' | 'mfa';

export default function LoginPage() {
    const [providers, setProviders] = useState<AuthProvider[]>([]);
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [mfaCode, setMfaCode] = useState('');
    const [mfaToken, setMfaToken] = useState('');
    const [stage, setStage] = useState<Stage>('credentials');
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(false);

    // Fetch enabled providers so we render the right buttons.
    useEffect(() => {
        api.get('/auth/providers')
            .then(res => setProviders(res.data?.providers || []))
            .catch(() => setProviders([{ name: 'local', credentials: true, redirect: false, display_name: 'Local account' }]));
    }, []);

    const credentialProviders = providers.filter(p => p.credentials);
    const redirectProviders = providers.filter(p => p.redirect && p.login_url);

    const handleLogin = async (e: React.FormEvent) => {
        e.preventDefault();
        setError('');
        setLoading(true);

        try {
            const response = await api.post('/auth/login', { username, password });

            // Forced TOTP enrolment (policy-driven). Hand off to the
            // dedicated /auth/forced-mfa-setup page carrying the setup
            // token. User cannot get a session before completing it.
            if (response.data?.mfa_setup_required && response.data?.setup_token) {
                window.location.href = `/mfa-setup?token=${encodeURIComponent(response.data.setup_token)}`;
                return;
            }

            // Backend signals MFA needed — switch to second-factor stage.
            if (response.data?.mfa_required) {
                setMfaToken(response.data.mfa_token);
                setStage('mfa');
                setLoading(false);
                return;
            }

            if (response.data?.access_token) {
                window.location.href = '/';
                return;
            }
            setError('Login failed: no access token received.');
        } catch (err: any) {
            const status = err.response?.status;
            const detail = err.response?.data?.detail;
            if (status === 403) setError(detail || 'Account locked or deactivated.');
            else if (status === 429) setError('Too many login attempts. Please wait a moment.');
            else if (status === 401) setError('Invalid username or password.');
            else setError(detail || 'Login failed. Please try again.');
        } finally {
            setLoading(false);
        }
    };

    const handleMfaVerify = async (e: React.FormEvent) => {
        e.preventDefault();
        setError('');
        setLoading(true);
        try {
            const response = await api.post('/auth/mfa/verify', {
                mfa_token: mfaToken,
                code: mfaCode,
            });
            if (response.data?.access_token) {
                window.location.href = '/';
                return;
            }
            setError('MFA verification failed.');
        } catch (err: any) {
            const detail = err.response?.data?.detail;
            setError(detail || 'Invalid or expired MFA code.');
        } finally {
            setLoading(false);
        }
    };

    return (
        <div className="flex min-h-screen flex-col justify-center px-6 py-12 lg:px-8 bg-gray-50">
            <div className="sm:mx-auto sm:w-full sm:max-w-sm">
                <img src="/logo.svg" alt="VulnCheck Logo" className="mx-auto h-24 w-24" />
                <h2 className="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900 font-mono">
                    VulnCheck
                </h2>
                <p className="text-center text-sm text-gray-500 font-mono mt-2">
                    {stage === 'credentials' ? 'Sign in to your account' : 'Enter your verification code'}
                </p>
            </div>

            <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
                {stage === 'credentials' && (
                    <>
                        {/* SSO redirect buttons (OIDC / SAML) */}
                        {redirectProviders.length > 0 && (
                            <div className="space-y-2 mb-6">
                                {redirectProviders.map(p => (
                                    <a
                                        key={p.name}
                                        href={p.login_url || '#'}
                                        className="flex w-full items-center justify-center gap-2 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-semibold text-gray-700 shadow-sm hover:bg-gray-50 font-mono"
                                    >
                                        <span>Sign in with {p.display_name}</span>
                                    </a>
                                ))}
                                {credentialProviders.length > 0 && (
                                    <div className="relative my-4">
                                        <div className="absolute inset-0 flex items-center" aria-hidden="true">
                                            <div className="w-full border-t border-gray-300" />
                                        </div>
                                        <div className="relative flex justify-center text-xs">
                                            <span className="bg-gray-50 px-2 text-gray-500 font-mono uppercase">or</span>
                                        </div>
                                    </div>
                                )}
                            </div>
                        )}

                        {/* Local / LDAP credentials form */}
                        {credentialProviders.length > 0 && (
                            <form className="space-y-6" onSubmit={handleLogin}>
                                <div>
                                    <label htmlFor="username" className="block text-sm font-medium leading-6 text-gray-900 font-mono">
                                        Username
                                    </label>
                                    <div className="mt-2">
                                        <input
                                            id="username"
                                            name="username"
                                            type="text"
                                            autoComplete="username"
                                            required
                                            value={username}
                                            onChange={(e) => setUsername(e.target.value)}
                                            className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue sm:text-sm sm:leading-6"
                                        />
                                    </div>
                                </div>

                                <div>
                                    <label htmlFor="password" className="block text-sm font-medium leading-6 text-gray-900 font-mono">
                                        Password
                                    </label>
                                    <div className="mt-2">
                                        <input
                                            id="password"
                                            name="password"
                                            type="password"
                                            autoComplete="current-password"
                                            required
                                            value={password}
                                            onChange={(e) => setPassword(e.target.value)}
                                            className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue sm:text-sm sm:leading-6"
                                        />
                                    </div>
                                </div>

                                {error && (
                                    <div className="text-red-600 text-sm font-mono text-center bg-red-50 p-2 rounded">
                                        {error}
                                    </div>
                                )}

                                <div>
                                    <button
                                        type="submit"
                                        disabled={loading}
                                        className="flex w-full justify-center rounded-md bg-vulncheck-blue px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-blue-600 disabled:opacity-60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 font-mono"
                                    >
                                        {loading ? 'Signing in…' : 'Sign in'}
                                    </button>
                                </div>

                                {credentialProviders.length > 1 && (
                                    <p className="text-center text-[11px] text-gray-400 font-mono">
                                        Tries {credentialProviders.map(p => p.display_name).join(' → ')}
                                    </p>
                                )}
                            </form>
                        )}
                    </>
                )}

                {stage === 'mfa' && (
                    <form className="space-y-6" onSubmit={handleMfaVerify}>
                        <div>
                            <label htmlFor="mfa" className="block text-sm font-medium leading-6 text-gray-900 font-mono">
                                Authenticator code
                            </label>
                            <p className="text-xs text-gray-500 font-mono mt-1">
                                Open your authenticator app and enter the 6-digit code.
                            </p>
                            <div className="mt-2">
                                <input
                                    id="mfa"
                                    name="mfa"
                                    type="text"
                                    inputMode="numeric"
                                    pattern="[0-9]{6}"
                                    maxLength={6}
                                    autoComplete="one-time-code"
                                    autoFocus
                                    required
                                    value={mfaCode}
                                    onChange={(e) => setMfaCode(e.target.value.replace(/\D/g, ''))}
                                    className="block w-full rounded-md border-0 py-2 text-center text-xl tracking-[0.5em] font-mono text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue"
                                    placeholder="000000"
                                />
                            </div>
                        </div>

                        {error && (
                            <div className="text-red-600 text-sm font-mono text-center bg-red-50 p-2 rounded">
                                {error}
                            </div>
                        )}

                        <div className="flex gap-2">
                            <button
                                type="button"
                                onClick={() => { setStage('credentials'); setMfaCode(''); setMfaToken(''); setError(''); }}
                                className="flex-1 rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm font-semibold text-gray-700 hover:bg-gray-50 font-mono"
                            >
                                Back
                            </button>
                            <button
                                type="submit"
                                disabled={loading || mfaCode.length !== 6}
                                className="flex-[2] rounded-md bg-vulncheck-blue px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-600 disabled:opacity-60 font-mono"
                            >
                                {loading ? 'Verifying…' : 'Verify'}
                            </button>
                        </div>
                    </form>
                )}
            </div>
        </div>
    );
}
