'use client';

import { useCallback, useEffect, useState } from 'react';
import { useAuth } from '@/contexts/AuthContext';
import { getBrowserSupabase } from '@/lib/supabase';

// Mounts at the root layout. Checks Supabase's AAL (Authenticator Assurance
// Level) after every auth state change. If the user has MFA enrolled but
// their session is still at aal1, we block the UI with a code challenge
// until they reach aal2. Until verified, they can't see paid features.

type ChallengeState =
  | { status: 'idle' }
  | { status: 'needed'; factorId: string }
  | { status: 'verifying'; factorId: string; challengeId: string };

export default function MFAChallenge() {
  const { user, session } = useAuth();
  const [state, setState] = useState<ChallengeState>({ status: 'idle' });
  const [code, setCode] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  const evaluate = useCallback(async () => {
    const supabase = getBrowserSupabase();
    if (!supabase || !user) {
      setState({ status: 'idle' });
      return;
    }
    const aal = await supabase.auth.mfa.getAuthenticatorAssuranceLevel();
    if (aal.error) return;
    const { currentLevel, nextLevel } = aal.data;
    if (currentLevel === 'aal1' && nextLevel === 'aal2') {
      const { data } = await supabase.auth.mfa.listFactors();
      const factor = (data?.totp ?? []).find((f) => f.status === 'verified');
      if (factor) {
        setState({ status: 'needed', factorId: factor.id });
        return;
      }
    }
    setState({ status: 'idle' });
  }, [user]);

  useEffect(() => {
    void evaluate();
  }, [evaluate, session?.access_token]);

  const issueChallenge = async () => {
    if (state.status !== 'needed') return;
    const supabase = getBrowserSupabase();
    if (!supabase) return;
    const { data, error: cErr } = await supabase.auth.mfa.challenge({ factorId: state.factorId });
    if (cErr || !data) {
      setError(cErr?.message ?? 'Could not start MFA challenge.');
      return;
    }
    setState({ status: 'verifying', factorId: state.factorId, challengeId: data.id });
  };

  const submit = async () => {
    if (state.status !== 'verifying') return;
    const supabase = getBrowserSupabase();
    if (!supabase) return;
    setSubmitting(true);
    setError(null);
    try {
      const res = await supabase.auth.mfa.verify({
        factorId: state.factorId,
        challengeId: state.challengeId,
        code,
      });
      if (res.error) {
        setError(res.error.message);
        return;
      }
      setCode('');
      setState({ status: 'idle' });
    } finally {
      setSubmitting(false);
    }
  };

  if (state.status === 'idle') return null;

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-label="Two-factor authentication required"
      className="fixed inset-0 z-[60] flex items-center justify-center bg-black/85 p-4"
    >
      <div
        className="w-full max-w-sm rounded-lg border p-5"
        style={{ background: 'var(--bg-surface)', borderColor: 'var(--border-light)' }}
      >
        <h2 className="text-lg font-semibold" style={{ color: 'var(--text-primary)' }}>
          Two-factor required
        </h2>
        <p className="mt-2 text-sm" style={{ color: 'var(--text-secondary)' }}>
          Enter the 6-digit code from your authenticator app.
        </p>
        <input
          inputMode="numeric"
          pattern="[0-9]*"
          maxLength={6}
          autoFocus
          value={code}
          onChange={(e) => setCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
          className="mt-4 w-full rounded border px-3 py-2 text-center text-lg tracking-widest"
          style={{
            background: 'var(--bg-elevated)',
            borderColor: 'var(--border-light)',
            color: 'var(--text-primary)',
          }}
          placeholder="123456"
        />
        {error && (
          <p className="mt-2 text-xs" style={{ color: 'var(--grade-d)' }}>
            {error}
          </p>
        )}
        <div className="mt-4 flex gap-2">
          {state.status === 'needed' ? (
            <button
              type="button"
              onClick={issueChallenge}
              className="w-full rounded px-4 py-2 text-sm font-semibold"
              style={{ background: 'var(--grade-a)', color: 'var(--bg-0)' }}
            >
              Continue
            </button>
          ) : (
            <button
              type="button"
              onClick={submit}
              disabled={code.length !== 6 || submitting}
              className="w-full rounded px-4 py-2 text-sm font-semibold disabled:opacity-50"
              style={{ background: 'var(--grade-a)', color: 'var(--bg-0)' }}
            >
              {submitting ? 'Verifying…' : 'Verify'}
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
