'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import type { MfaState } from '@/lib/security/mfa'

/**
 * Settings → Security (2026-09-22): two-factor authentication with an
 * authenticator app. Required for admin accounts, optional for others.
 */
async function call(body: Record<string, unknown>) {
  const r = await fetch('/api/auth/mfa', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) })
  const json = await r.json().catch(() => ({}))
  if (!r.ok) throw new Error(json.error ?? 'Something went wrong.')
  return json
}

export function SecurityCard({ state, isAdmin }: { state: MfaState; isAdmin: boolean }) {
  const router = useRouter()
  const [enrol, setEnrol] = useState<{ secret: string; qrDataUrl: string } | null>(null)
  const [code, setCode] = useState('')
  const [codes, setCodes] = useState<string[] | null>(null)
  const [busy, setBusy] = useState(false)
  const [mode, setMode] = useState<'idle' | 'disable' | 'recovery'>('idle')

  async function run(fn: () => Promise<void>) {
    setBusy(true)
    try { await fn() } catch (e) { toast.error(e instanceof Error ? e.message : 'Something went wrong.') } finally { setBusy(false) }
  }

  return (
    <Card className="mt-6">
      <CardContent className="pt-6">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <h3 className="text-sm font-bold uppercase tracking-wide text-neutral-500">Security · two-factor authentication</h3>
          <span className={`rounded-full px-2.5 py-0.5 text-[11px] font-semibold ring-1 ring-inset ${state.enabled ? 'bg-green-50 text-green-700 ring-green-200' : isAdmin ? 'bg-red-50 text-red-700 ring-red-200' : 'bg-neutral-100 text-neutral-600 ring-neutral-200'}`}>
            {state.enabled ? 'Enabled' : isAdmin ? 'Required — not enabled' : 'Not enabled'}
          </span>
        </div>
        {!state.available && <p className="mt-2 text-xs text-amber-800">Two-factor authentication needs database migration 0027.</p>}

        {codes ? (
          <div className="mt-3 rounded-xl border border-amber-200 bg-amber-50 p-4">
            <p className="text-sm font-bold text-amber-900">Save these recovery codes now — they are shown only once.</p>
            <p className="mt-1 text-xs text-amber-800">Each works once if you lose your phone. Keep them somewhere safe, not in this browser.</p>
            <ul className="mt-3 grid grid-cols-2 gap-1 font-mono text-sm">
              {codes.map((c) => <li key={c} className="rounded bg-white px-2 py-1">{c}</li>)}
            </ul>
            <div className="mt-3 flex gap-2">
              <Button size="sm" variant="outline" onClick={() => { navigator.clipboard.writeText(codes.join('\n')); toast.success('Copied') }}>Copy</Button>
              <Button size="sm" onClick={() => { setCodes(null); router.refresh() }}>I saved them</Button>
            </div>
          </div>
        ) : state.enabled ? (
          <div className="mt-3 space-y-3">
            <p className="text-xs text-neutral-600">Enabled {state.enabledAt ? new Date(state.enabledAt).toLocaleDateString() : ''} · {state.recoveryCodesLeft} recovery code{state.recoveryCodesLeft === 1 ? '' : 's'} left. Every sign-in asks for a code from your authenticator app.</p>
            {mode === 'idle' ? (
              <div className="flex flex-wrap gap-2">
                <Button size="sm" variant="outline" onClick={() => setMode('recovery')}>New recovery codes</Button>
                <Button size="sm" variant="outline" onClick={() => setMode('disable')} disabled={isAdmin}>{isAdmin ? 'Required for admins' : 'Turn off'}</Button>
              </div>
            ) : (
              <div className="flex flex-wrap items-end gap-2">
                <label className="text-xs font-semibold text-neutral-600">Current code<Input value={code} onChange={(e) => setCode(e.target.value)} placeholder="123 456" className="mt-1 w-40 font-mono" /></label>
                <Button size="sm" disabled={busy || code.length < 6} onClick={() => run(async () => {
                  if (mode === 'disable') { await call({ op: 'disable', code }); toast.success('Two-factor authentication turned off'); router.refresh() }
                  else { const r = await call({ op: 'recovery', code }); setCodes(r.recoveryCodes) }
                  setCode(''); setMode('idle')
                })}>{mode === 'disable' ? 'Turn off' : 'Generate'}</Button>
                <Button size="sm" variant="ghost" onClick={() => { setMode('idle'); setCode('') }}>Cancel</Button>
              </div>
            )}
          </div>
        ) : enrol ? (
          <div className="mt-3 grid gap-4 sm:grid-cols-[220px_1fr]">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img src={enrol.qrDataUrl} alt="Scan with your authenticator app" className="h-[220px] w-[220px] rounded-lg border bg-white" />
            <div className="space-y-2 text-xs text-neutral-600">
              <p><span className="font-bold text-neutral-800">1.</span> Scan the code with Google Authenticator, Authy, 1Password or Microsoft Authenticator. Or enter this key by hand:</p>
              <p className="select-all rounded bg-neutral-100 px-2 py-1 font-mono text-[11px] tracking-wider">{enrol.secret}</p>
              <p><span className="font-bold text-neutral-800">2.</span> Enter the 6-digit code the app shows to finish:</p>
              <div className="flex flex-wrap gap-2">
                <Input value={code} onChange={(e) => setCode(e.target.value)} placeholder="123 456" inputMode="numeric" className="w-40 font-mono" />
                <Button size="sm" disabled={busy || code.replace(/\s/g, '').length !== 6} onClick={() => run(async () => { const r = await call({ op: 'confirm', code }); setEnrol(null); setCode(''); setCodes(r.recoveryCodes); toast.success('Two-factor authentication enabled') })}>Enable</Button>
                <Button size="sm" variant="ghost" onClick={() => { setEnrol(null); setCode('') }}>Cancel</Button>
              </div>
            </div>
          </div>
        ) : (
          <div className="mt-3">
            <p className="text-xs text-neutral-600">{isAdmin ? 'Admin accounts must use an authenticator app as a second sign-in step. It takes a minute to set up.' : 'Add an authenticator app as a second sign-in step. Recommended for anyone who manages a company.'}</p>
            <Button size="sm" className="mt-3" disabled={busy || !state.available} onClick={() => run(async () => { const r = await call({ op: 'begin' }); setEnrol({ secret: r.secret, qrDataUrl: r.qrDataUrl }) })}>Set up two-factor authentication</Button>
          </div>
        )}
      </CardContent>
    </Card>
  )
}
