'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useId, useRef, useState } from 'react';
import { QRCodeSVG } from 'qrcode.react';
import { toast } from 'sonner';
import { AlertTriangle, Check, Copy, Download, Loader2, ShieldCheck, ShieldAlert, } from 'lucide-react';
import { SecurityCard, StatusRow } from '../settings/securityPrimitives.js';
import { useMfaEnrollment } from './useMfaEnrollment.js';
function FieldError({ id, message }) {
    if (!message)
        return null;
    return (_jsx("p", { id: id, role: "alert", className: "text-destructive mt-1.5 text-sm", children: message }));
}
export function AccountSecurity() {
    const headingId = useId();
    const pwId = useId();
    const pwErrId = useId();
    const codeId = useId();
    const codeErrId = useId();
    const disablePwId = useId();
    const disableErrId = useId();
    const mfa = useMfaEnrollment();
    const [step, setStep] = useState('idle');
    const [password, setPassword] = useState('');
    const [verifyCode, setVerifyCode] = useState('');
    const [setupError, setSetupError] = useState(null);
    const [codeError, setCodeError] = useState(null);
    const [savedAcknowledged, setSavedAcknowledged] = useState(false);
    const [disabling, setDisabling] = useState(false);
    const [disablePassword, setDisablePassword] = useState('');
    const [disableError, setDisableError] = useState(null);
    const codeInputRef = useRef(null);
    function resetSetup() {
        mfa.cancelSetup();
        setStep('idle');
        setPassword('');
        setVerifyCode('');
        setSetupError(null);
        setCodeError(null);
        setSavedAcknowledged(false);
    }
    async function handleBeginSetup() {
        setSetupError(null);
        const result = await mfa.beginSetup(password);
        if (!result.ok) {
            setSetupError(result.error ?? 'Could not start MFA setup.');
            return;
        }
        setPassword('');
        setStep('enroll');
        // Move focus to the code field once the QR is shown.
        requestAnimationFrame(() => codeInputRef.current?.focus());
    }
    async function handleConfirmSetup() {
        setCodeError(null);
        const result = await mfa.confirmSetup(verifyCode);
        if (!result.ok) {
            setCodeError(result.error ?? 'That code did not match. Try the current one.');
            return;
        }
        toast.success('Two-factor authentication is now enabled.');
        resetSetup();
    }
    async function handleDisable() {
        setDisableError(null);
        const result = await mfa.disable(disablePassword);
        if (!result.ok) {
            setDisableError(result.error ?? 'Could not disable MFA.');
            return;
        }
        toast.success('Two-factor authentication has been disabled.');
        setDisabling(false);
        setDisablePassword('');
    }
    function copyBackupCodes() {
        if (!mfa.enrollment)
            return;
        void navigator.clipboard
            ?.writeText(mfa.enrollment.backupCodes.join('\n'))
            .then(() => toast.success('Backup codes copied to clipboard.'))
            .catch(() => toast.error('Could not copy codes. Copy them manually.'));
    }
    function downloadBackupCodes() {
        if (!mfa.enrollment)
            return;
        const blob = new Blob([
            'Actuate CMS — two-factor backup codes\n',
            'Each code can be used once if you lose access to your authenticator app.\n\n',
            mfa.enrollment.backupCodes.join('\n'),
            '\n',
        ], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'actuate-backup-codes.txt';
        a.click();
        URL.revokeObjectURL(url);
    }
    return (_jsxs(SecurityCard, { headingId: headingId, title: "Two-factor authentication", description: "Add a one-time code from an authenticator app to your sign-in for an extra layer of protection.", children: [mfa.status === 'loading' && (_jsxs("div", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Checking your MFA status\u2026"] })), mfa.status === 'error' && (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: "Could not load your MFA status." }), _jsx("button", { type: "button", onClick: () => void mfa.refresh(), className: "border-border text-foreground hover:bg-accent rounded-md border px-3 py-1.5 text-sm transition-colors", children: "Retry" })] })), mfa.status === 'enabled' && (_jsxs("div", { className: "space-y-4", children: [_jsx(StatusRow, { status: "pass", label: "Two-factor authentication", value: "Enabled" }), !disabling ? (_jsxs("button", { type: "button", onClick: () => {
                            setDisabling(true);
                            setDisableError(null);
                        }, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm transition-colors", children: [_jsx(ShieldAlert, { size: 16, "aria-hidden": "true" }), "Disable two-factor"] })) : (_jsxs("div", { className: "border-destructive/30 bg-destructive/5 space-y-3 rounded-md border p-3", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertTriangle, { size: 16, className: "text-destructive mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("p", { className: "text-foreground text-sm", children: "Disabling two-factor makes your account password-only and signs out your other sessions. Confirm your password to continue." })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: disablePwId, className: "text-foreground mb-1 block text-sm font-medium", children: "Current password" }), _jsx("input", { id: disablePwId, type: "password", autoComplete: "current-password", value: disablePassword, onChange: (e) => setDisablePassword(e.target.value), "aria-invalid": disableError ? true : undefined, "aria-describedby": disableError ? disableErrId : undefined, className: "border-border bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none" }), _jsx(FieldError, { id: disableErrId, message: disableError })] }), _jsxs("div", { className: "flex items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: () => {
                                            setDisabling(false);
                                            setDisablePassword('');
                                            setDisableError(null);
                                        }, className: "text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors", children: "Cancel" }), _jsxs("button", { type: "button", onClick: () => void handleDisable(), disabled: mfa.busy || !disablePassword, className: "bg-destructive text-destructive-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: [mfa.busy && _jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Disable two-factor"] })] })] }))] })), mfa.status === 'disabled' && step === 'idle' && (_jsxs("div", { className: "space-y-4", children: [_jsx(StatusRow, { status: "warning", label: "Two-factor authentication", value: "Not set up" }), _jsxs("button", { type: "button", onClick: () => {
                            setStep('reauth');
                            setSetupError(null);
                        }, className: "bg-brand text-brand-foreground focus-visible:ring-ring inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 focus-visible:ring-2 focus-visible:outline-none", children: [_jsx(ShieldCheck, { size: 16, "aria-hidden": "true" }), "Set up two-factor"] })] })), mfa.status === 'disabled' && step === 'reauth' && (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: "Confirm your current password to begin setting up two-factor authentication." }), _jsxs("div", { children: [_jsx("label", { htmlFor: pwId, className: "text-foreground mb-1 block text-sm font-medium", children: "Current password" }), _jsx("input", { id: pwId, type: "password", autoComplete: "current-password", value: password, onChange: (e) => setPassword(e.target.value), autoFocus: true, "aria-invalid": setupError ? true : undefined, "aria-describedby": setupError ? pwErrId : undefined, onKeyDown: (e) => {
                                    if (e.key === 'Enter' && password && !mfa.busy)
                                        void handleBeginSetup();
                                }, className: "border-border bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none" }), _jsx(FieldError, { id: pwErrId, message: setupError })] }), _jsxs("div", { className: "flex items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: resetSetup, className: "text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors", children: "Cancel" }), _jsxs("button", { type: "button", onClick: () => void handleBeginSetup(), disabled: mfa.busy || !password, className: "bg-brand text-brand-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: [mfa.busy && _jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Continue"] })] })] })), mfa.status === 'disabled' && step === 'enroll' && mfa.enrollment && (_jsxs("div", { className: "space-y-5", children: [_jsxs("ol", { className: "text-foreground list-decimal space-y-4 pl-5 text-sm", children: [_jsxs("li", { children: [_jsx("p", { className: "font-medium", children: "Scan this QR code with your authenticator app." }), _jsx("div", { className: "border-border bg-card mt-2 inline-flex rounded-lg border p-3", children: _jsx(QRCodeSVG, { value: mfa.enrollment.uri, size: 160, role: "img", "aria-label": "Two-factor setup QR code" }) }), _jsx("p", { className: "text-muted-foreground mt-2", children: "Can't scan? Enter this key manually:" }), _jsx("code", { className: "border-border bg-muted text-foreground mt-1 inline-block rounded border px-2 py-1 font-mono text-xs break-all", children: mfa.enrollment.secret })] }), _jsxs("li", { children: [_jsx("p", { className: "font-medium", children: "Save your backup codes." }), _jsx("p", { className: "text-muted-foreground mt-0.5", children: "Each code works once if you lose your authenticator. They won't be shown again." }), _jsx("ul", { className: "border-border bg-muted/40 mt-2 grid grid-cols-2 gap-x-6 gap-y-1 rounded-md border p-3 font-mono text-xs sm:grid-cols-4", children: mfa.enrollment.backupCodes.map((code) => (_jsx("li", { className: "text-foreground", children: code }, code))) }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-2", children: [_jsxs("button", { type: "button", onClick: copyBackupCodes, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs transition-colors", children: [_jsx(Copy, { size: 14, "aria-hidden": "true" }), "Copy codes"] }), _jsxs("button", { type: "button", onClick: downloadBackupCodes, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs transition-colors", children: [_jsx(Download, { size: 14, "aria-hidden": "true" }), "Download"] })] }), _jsxs("label", { className: "text-foreground mt-2 flex items-center gap-2 text-sm", children: [_jsx("input", { type: "checkbox", checked: savedAcknowledged, onChange: (e) => setSavedAcknowledged(e.target.checked), className: "accent-brand h-4 w-4" }), "I've saved my backup codes somewhere safe."] })] }), _jsxs("li", { children: [_jsx("p", { className: "font-medium", children: "Enter the 6-digit code from your app to finish." }), _jsxs("div", { className: "mt-2", children: [_jsx("label", { htmlFor: codeId, className: "sr-only", children: "Authentication code" }), _jsx("input", { id: codeId, ref: codeInputRef, inputMode: "numeric", autoComplete: "one-time-code", maxLength: 6, placeholder: "123456", value: verifyCode, onChange: (e) => setVerifyCode(e.target.value.replace(/\D/g, '')), "aria-invalid": codeError ? true : undefined, "aria-describedby": codeError ? codeErrId : undefined, onKeyDown: (e) => {
                                                    if (e.key === 'Enter' && savedAcknowledged && !mfa.busy)
                                                        void handleConfirmSetup();
                                                }, className: "border-border bg-input-background text-foreground focus-visible:ring-ring w-40 rounded-md border px-3 py-2 text-center font-mono text-lg tracking-[0.3em] focus-visible:ring-2 focus-visible:outline-none" }), _jsx(FieldError, { id: codeErrId, message: codeError })] })] })] }), _jsxs("div", { className: "flex items-center justify-end gap-3", children: [_jsx("button", { type: "button", onClick: resetSetup, className: "text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors", children: "Cancel" }), _jsxs("button", { type: "button", onClick: () => void handleConfirmSetup(), disabled: mfa.busy || !savedAcknowledged || verifyCode.length !== 6, className: "bg-brand text-brand-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: [mfa.busy ? (_jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" })) : (_jsx(Check, { size: 16, "aria-hidden": "true" })), "Verify & enable"] })] })] }))] }));
}
//# sourceMappingURL=AccountSecurity.js.map