"use client";

import { useEffect, useState } from "react";
import { QRCodeSVG } from "qrcode.react";
import api from "../../lib/api";

type AuthMeResponse = {
    id: number;
    username: string;
    email: string;
    role: string;
    auth_provider?: "local" | "ldap" | "saml" | "oidc";
    mfa_enabled?: boolean;
};

type SetupResponse = {
    secret: string;
    provisioning_uri: string;
};

type Stage = "idle" | "setup" | "activate" | "disable";

/**
 * TOTP (RFC 6238) enrolment card for the Settings → Profile page.
 *
 * Flow:
 *   idle → "Enable MFA" → enter password → /auth/mfa/setup → setup → enter 6-digit code → /auth/mfa/activate → idle (enabled)
 *   idle (enabled) → "Disable MFA" → enter password → /auth/mfa/disable → idle (disabled)
 */
export default function MfaCard() {
    const [me, setMe] = useState<AuthMeResponse | null>(null);
    const [stage, setStage] = useState<Stage>("idle");
    const [password, setPassword] = useState("");
    const [secret, setSecret] = useState("");
    const [uri, setUri] = useState("");
    const [code, setCode] = useState("");
    const [err, setErr] = useState("");
    const [busy, setBusy] = useState(false);

    const refresh = async () => {
        try {
            const res = await api.get("/auth/me");
            setMe(res.data);
        } catch {
            setMe(null);
        }
    };

    useEffect(() => { refresh(); }, []);

    const reset = () => {
        setStage("idle");
        setPassword("");
        setSecret("");
        setUri("");
        setCode("");
        setErr("");
    };

    const startSetup = async (e: React.FormEvent) => {
        e.preventDefault();
        setBusy(true);
        setErr("");
        try {
            const res = await api.post<SetupResponse>("/auth/mfa/setup", { password });
            setSecret(res.data.secret);
            setUri(res.data.provisioning_uri);
            setStage("activate");
            setPassword("");
        } catch (e: any) {
            setErr(e?.response?.data?.detail || "Setup failed");
        } finally {
            setBusy(false);
        }
    };

    const activate = async (e: React.FormEvent) => {
        e.preventDefault();
        setBusy(true);
        setErr("");
        try {
            await api.post("/auth/mfa/activate", { code });
            await refresh();
            reset();
        } catch (e: any) {
            setErr(e?.response?.data?.detail || "Activation failed");
        } finally {
            setBusy(false);
        }
    };

    const disable = async (e: React.FormEvent) => {
        e.preventDefault();
        setBusy(true);
        setErr("");
        try {
            await api.post("/auth/mfa/disable", { password });
            await refresh();
            reset();
        } catch (e: any) {
            setErr(e?.response?.data?.detail || "Disable failed");
        } finally {
            setBusy(false);
        }
    };

    // SAML / OIDC users get MFA from their IdP — no second factor here.
    // LDAP users *can* enrol: password is verified via LDAP rebind.
    const mfaEligible = !me || me.auth_provider === "local" || me.auth_provider === "ldap";
    if (me && !mfaEligible) {
        return (
            <div className="bg-white border border-gray-200 shadow-sm rounded-sm p-6 mt-4">
                <h3 className="text-lg font-bold text-gray-900 font-mono mb-2 border-b border-gray-100 pb-2">
                    Two-factor authentication
                </h3>
                <p className="text-sm text-gray-500 font-mono">
                    Your account is managed by an external identity provider
                    ({me.auth_provider?.toUpperCase()}). Configure MFA in your IdP, not here.
                </p>
            </div>
        );
    }

    const isLdap = me?.auth_provider === "ldap";

    return (
        <div className="bg-white border border-gray-200 shadow-sm rounded-sm p-6 mt-4">
            <div className="flex items-center justify-between mb-4 border-b border-gray-100 pb-2">
                <h3 className="text-lg font-bold text-gray-900 font-mono">
                    Two-factor authentication
                </h3>
                {me?.mfa_enabled ? (
                    <span className="inline-flex items-center rounded bg-green-100 px-2 py-0.5 text-xs font-bold text-green-700 font-mono uppercase">
                        Enabled
                    </span>
                ) : (
                    <span className="inline-flex items-center rounded bg-gray-100 px-2 py-0.5 text-xs font-bold text-gray-500 font-mono uppercase">
                        Disabled
                    </span>
                )}
            </div>

            <p className="text-sm text-gray-500 font-mono mb-4">
                Adds a 6-digit code from your authenticator app (Aegis, Google Authenticator,
                1Password, etc.) on top of your password. Strongly recommended for admin accounts.
            </p>

            {err && (
                <div className="text-red-600 text-sm font-mono bg-red-50 border border-red-200 rounded p-2 mb-3">
                    {err}
                </div>
            )}

            {/* ---------- IDLE ---------- */}
            {stage === "idle" && (
                <div className="flex gap-2">
                    {me?.mfa_enabled ? (
                        <button
                            onClick={() => { reset(); setStage("disable"); }}
                            className="rounded-md border border-red-300 bg-white px-3 py-1.5 text-sm font-semibold text-red-700 hover:bg-red-50 font-mono"
                        >
                            Disable MFA
                        </button>
                    ) : (
                        <button
                            onClick={() => { reset(); setStage("setup"); }}
                            className="rounded-md bg-vulncheck-blue px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-600 font-mono"
                        >
                            Enable MFA
                        </button>
                    )}
                </div>
            )}

            {/* ---------- SETUP: confirm password ---------- */}
            {stage === "setup" && (
                <form onSubmit={startSetup} className="space-y-3">
                    <label className="block text-sm font-mono text-gray-700">
                        {isLdap
                            ? "Confirm your LDAP password to generate an MFA secret. We verify by re-binding to your directory — the password is not stored."
                            : "Confirm your current password to generate an MFA secret:"}
                    </label>
                    <input
                        type="password"
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        autoComplete="current-password"
                        required
                        className="block w-full rounded-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue sm:text-sm font-mono"
                    />
                    <div className="flex gap-2">
                        <button type="button" onClick={reset} className="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50 font-mono">Cancel</button>
                        <button type="submit" disabled={busy} className="rounded-md bg-vulncheck-blue px-3 py-1.5 text-sm font-semibold text-white hover:bg-blue-600 disabled:opacity-60 font-mono">
                            {busy ? "Generating…" : "Continue"}
                        </button>
                    </div>
                </form>
            )}

            {/* ---------- ACTIVATE: scan QR + enter code ---------- */}
            {stage === "activate" && (
                <form onSubmit={activate} className="space-y-3">
                    <div className="text-sm font-mono text-gray-700">
                        Step 1 — scan this QR code with your authenticator app, or paste the secret manually:
                    </div>
                    <div className="flex flex-col sm:flex-row gap-4 items-start">
                        <div className="bg-white border border-gray-200 p-2 rounded">
                            <QRCodeSVG value={uri} size={180} level="M" />
                        </div>
                        <div className="flex-1 min-w-0">
                            <div className="text-[11px] font-mono text-gray-500 uppercase tracking-wider mb-1">Secret</div>
                            <input
                                readOnly
                                value={secret}
                                onClick={(e) => (e.target as HTMLInputElement).select()}
                                className="w-full text-xs font-mono break-all border border-gray-300 rounded px-2 py-1 bg-gray-50"
                            />
                            <div className="text-[11px] text-gray-400 mt-2 break-all">
                                {uri}
                            </div>
                        </div>
                    </div>

                    <div>
                        <label className="block text-sm font-mono text-gray-700 mb-1">
                            Step 2 — enter the 6-digit code your app shows:
                        </label>
                        <input
                            type="text"
                            inputMode="numeric"
                            pattern="[0-9]{6}"
                            maxLength={6}
                            value={code}
                            onChange={(e) => setCode(e.target.value.replace(/\D/g, ""))}
                            autoComplete="one-time-code"
                            autoFocus
                            placeholder="000000"
                            className="w-40 text-center text-xl tracking-[0.5em] font-mono rounded-md border-0 py-2 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue"
                        />
                    </div>

                    <div className="flex gap-2">
                        <button type="button" onClick={reset} className="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50 font-mono">Cancel</button>
                        <button type="submit" disabled={busy || code.length !== 6} className="rounded-md bg-vulncheck-blue px-3 py-1.5 text-sm font-semibold text-white hover:bg-blue-600 disabled:opacity-60 font-mono">
                            {busy ? "Activating…" : "Activate MFA"}
                        </button>
                    </div>
                </form>
            )}

            {/* ---------- DISABLE ---------- */}
            {stage === "disable" && (
                <form onSubmit={disable} className="space-y-3">
                    <label className="block text-sm font-mono text-gray-700">
                        {isLdap
                            ? "Confirm your LDAP password to disable MFA:"
                            : "Confirm your current password to disable MFA:"}
                    </label>
                    <input
                        type="password"
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        autoComplete="current-password"
                        required
                        className="block w-full rounded-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue sm:text-sm font-mono"
                    />
                    <div className="flex gap-2">
                        <button type="button" onClick={reset} className="rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50 font-mono">Cancel</button>
                        <button type="submit" disabled={busy} className="rounded-md bg-red-600 px-3 py-1.5 text-sm font-semibold text-white hover:bg-red-700 disabled:opacity-60 font-mono">
                            {busy ? "Disabling…" : "Disable MFA"}
                        </button>
                    </div>
                </form>
            )}
        </div>
    );
}
