'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { notExpired } from '@/lib/domain/time'

const BTN = 'rounded-lg bg-[#0f1b2d] px-3 py-1.5 text-xs font-bold text-white disabled:opacity-50'
const BTN_SOFT = 'rounded-lg border px-3 py-1.5 text-xs font-bold text-neutral-800 disabled:opacity-50'
const LIMIT_LABELS: Record<string, string> = {
  unverified_per_day: 'Unverified · per day', verified_per_day: 'Verified · per day', company_verified_per_day: 'Company verified · per day', invited_per_day: 'Invited / trusted · per day',
  ip_per_hour: 'Per IP · per hour', page_per_hour: 'Per page · per hour', page_protection_per_hour: 'Protection mode at · per hour', protection_hours: 'Protection lasts · hours',
  verification_emails_per_15min: 'Codes per address · 15 min', max_files: 'Max files', max_file_mb: 'Max MB per file', max_total_mb: 'Max MB per submission', duplicate_window_hours: 'Duplicate window · hours',
  review_risk_score: 'Review at risk ≥', block_risk_score: 'Block at risk ≥',
}

async function call(body: Record<string, unknown>) {
  const r = await fetch('/api/admin/intake-security', { 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
}

type Submission = { id: string; broker_page_id: string; status: string; reason: string | null; risk_score: number | null; contact_email: string; source_ip: string | null; created_at: string; trip_id: string | null; user_id: string | null }
type Page = { id: string; slug: string; display_name: string; intake_enabled: boolean | null; who_can_submit: string | null; protection_mode: boolean | null; protection_reason: string | null; protection_until: string | null }
type Block = { id: string; kind: string; value: string; reason: string | null; until: string | null; created_by: string | null; created_at: string }
type Event = { event: string; username: string | null; ip: string | null; detail: Record<string, unknown> | null; created_at: string }

export function IntakeSecurityConsole({ submissions, pages, blocks, limits, events }: { submissions: Submission[]; pages: Page[]; blocks: Block[]; limits: Record<string, number> | null; events: Event[] }) {
  const router = useRouter()
  const [busy, setBusy] = useState(false)
  const [block, setBlock] = useState({ kind: 'ip', value: '', reason: '', hours: '24' })
  const [edit, setEdit] = useState<Record<string, number>>(Object.fromEntries(Object.entries(limits ?? {}).filter(([k, v]) => typeof v === 'number' && LIMIT_LABELS[k]) as [string, number][]))
  async function run(fn: () => Promise<unknown>, done: string) {
    setBusy(true)
    try { await fn(); toast.success(done); router.refresh() } catch (e) { toast.error(e instanceof Error ? e.message : 'Something went wrong.') } finally { setBusy(false) }
  }
  const count = (s: string) => submissions.filter((x) => x.status === s).length
  const stats = [
    ['Submissions', submissions.length], ['Accepted', count('accepted') + count('received')], ['Under review', count('review_required')], ['Rejected', count('rejected')],
    ['Blocked', count('blocked')], ['Duplicates', count('duplicate')], ['Pages in protection', pages.filter((p) => p.protection_mode).length], ['Active blocks', blocks.filter((b) => notExpired(b.until)).length],
  ] as const
  const byIp = Object.entries(submissions.reduce<Record<string, number>>((a, s) => { if (s.source_ip) a[s.source_ip] = (a[s.source_ip] ?? 0) + 1; return a }, {})).sort((a, b) => b[1] - a[1]).slice(0, 8)
  return (
    <div className="space-y-6">
      <dl className="grid grid-cols-2 gap-2 sm:grid-cols-4 lg:grid-cols-8">
        {stats.map(([k, v]) => <div key={k} className="rounded-xl border bg-white p-3"><dt className="text-[10px] font-bold uppercase text-neutral-500">{k}</dt><dd className="text-lg font-bold">{v}</dd></div>)}
      </dl>

      <div className="grid gap-4 lg:grid-cols-2">
        <div className="rounded-2xl border bg-white p-5">
          <h2 className="font-bold">Broker intake pages</h2>
          <ul className="mt-2 divide-y text-sm">
            {pages.map((p) => (
              <li key={p.id} className="flex flex-wrap items-center justify-between gap-2 py-2">
                <div><span className="font-semibold">{p.display_name}</span> <span className="text-xs text-neutral-500">/intake/{p.slug}</span>
                  <div className="text-[11px] text-neutral-500">{p.intake_enabled === false ? 'disabled' : 'enabled'} · {(p.who_can_submit ?? 'verified_email').replace(/_/g, ' ')}{p.protection_mode ? ` · PROTECTION MODE${p.protection_reason ? ` (${p.protection_reason})` : ''}` : ''}</div>
                </div>
                <div className="flex flex-wrap gap-1.5">
                  <button disabled={busy} onClick={() => run(() => call({ op: 'page', page_id: p.id, intake_enabled: p.intake_enabled === false }), 'Saved')} className={BTN_SOFT}>{p.intake_enabled === false ? 'Enable' : 'Disable'}</button>
                  <button disabled={busy} onClick={() => run(() => call({ op: 'page', page_id: p.id, protection_mode: !p.protection_mode }), 'Saved')} className={BTN_SOFT}>{p.protection_mode ? 'Lift protection' : 'Protection mode'}</button>
                  <select value={p.who_can_submit ?? 'verified_email'} onChange={(e) => run(() => call({ op: 'page', page_id: p.id, who_can_submit: e.target.value }), 'Saved')} className="rounded-lg border px-2 py-1 text-xs">
                    <option value="verified_email">Anyone with verified email</option><option value="verified_company">Verified carriers only</option><option value="invited_only">Invited only</option>
                  </select>
                </div>
              </li>
            ))}
          </ul>
        </div>
        <div className="rounded-2xl border bg-white p-5">
          <h2 className="font-bold">Blocks</h2>
          <div className="mt-2 flex flex-wrap items-end gap-2 text-xs">
            <select value={block.kind} onChange={(e) => setBlock({ ...block, kind: e.target.value })} className="rounded-lg border px-2 py-1.5"><option value="ip">IP</option><option value="email">Email</option><option value="user">User id</option></select>
            <input value={block.value} onChange={(e) => setBlock({ ...block, value: e.target.value })} placeholder="value" className="w-44 rounded-lg border px-2 py-1.5" />
            <input value={block.reason} onChange={(e) => setBlock({ ...block, reason: e.target.value })} placeholder="reason" className="w-36 rounded-lg border px-2 py-1.5" />
            <input value={block.hours} onChange={(e) => setBlock({ ...block, hours: e.target.value })} placeholder="hours (blank = permanent)" className="w-24 rounded-lg border px-2 py-1.5" />
            <button disabled={busy || !block.value} onClick={() => run(() => call({ op: 'block', kind: block.kind, value: block.value, reason: block.reason, hours: block.hours ? Number(block.hours) : undefined }), 'Blocked')} className={BTN}>Block</button>
          </div>
          <ul className="mt-3 max-h-56 space-y-1 overflow-y-auto text-xs">
            {blocks.length === 0 && <li className="text-neutral-500">No blocks.</li>}
            {blocks.map((b) => <li key={b.id} className="flex items-center justify-between gap-2 border-b py-1"><span><span className="font-mono">{b.kind}:{b.value}</span> {b.reason ? `· ${b.reason}` : ''}{b.until ? ` · until ${new Date(b.until).toLocaleString()}` : ' · permanent'}</span><button disabled={busy} onClick={() => run(() => call({ op: 'unblock', id: b.id }), 'Unblocked')} className="underline">remove</button></li>)}
          </ul>
          <h3 className="mt-4 text-xs font-bold uppercase text-neutral-500">Top IPs (24 h)</h3>
          <ul className="mt-1 text-xs">{byIp.map(([ip, n]) => <li key={ip} className="flex justify-between"><span className="font-mono">{ip}</span><span>{n} <button disabled={busy} onClick={() => run(() => call({ op: 'block', kind: 'ip', value: ip, reason: 'blocked from Intake Security', hours: 24 }), 'IP blocked for 24 h')} className="ml-2 underline">block 24h</button></span></li>)}</ul>
        </div>
      </div>

      <div className="rounded-2xl border bg-white p-5">
        <h2 className="font-bold">Recent submissions</h2>
        <div className="mt-2 overflow-x-auto">
          <table className="w-full min-w-[760px] text-xs">
            <thead><tr className="text-left text-[10px] uppercase text-neutral-500"><th className="py-1">When</th><th>Page</th><th>Email</th><th>IP</th><th>Status</th><th>Risk</th><th>Reason</th><th></th></tr></thead>
            <tbody>
              {submissions.length === 0 && <tr><td colSpan={8} className="py-2 text-neutral-500">No submissions in the last 24 hours.</td></tr>}
              {submissions.slice(0, 60).map((s) => (
                <tr key={s.id} className="border-t">
                  <td className="py-1">{new Date(s.created_at).toLocaleString()}</td><td>{pages.find((p) => p.id === s.broker_page_id)?.slug ?? '—'}</td><td>{s.contact_email}</td><td className="font-mono">{s.source_ip ?? '—'}</td>
                  <td><span className={`rounded-full px-2 py-0.5 text-[10px] font-semibold ${['accepted', 'received'].includes(s.status) ? 'bg-green-50 text-green-700' : s.status === 'review_required' ? 'bg-amber-50 text-amber-800' : 'bg-red-50 text-red-700'}`}>{s.status.replace(/_/g, ' ')}</span></td>
                  <td>{s.risk_score ?? '—'}</td><td>{s.reason?.replace(/_/g, ' ') ?? ''}</td>
                  <td className="text-right">{s.status === 'review_required' && <button disabled={busy} onClick={() => run(() => call({ op: 'release', submission_id: s.id }), 'Released')} className="underline">release</button>}{s.user_id && s.status !== 'blocked' && <button disabled={busy} onClick={() => run(() => call({ op: 'trust', user_id: s.user_id, level: 4 }), 'Marked trusted')} className="ml-2 underline">trust</button>}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-2">
        <div className="rounded-2xl border bg-white p-5">
          <h2 className="font-bold">Limits</h2>
          {!limits ? <p className="mt-2 text-xs text-neutral-500">Defaults in effect (migration 0029 not applied).</p> : (
            <>
              <div className="mt-2 grid gap-2 sm:grid-cols-2">
                {Object.entries(edit).map(([k, v]) => <label key={k} className="text-[11px] text-neutral-600">{LIMIT_LABELS[k]}<input type="number" value={v} onChange={(e) => setEdit({ ...edit, [k]: Number(e.target.value) })} className="mt-0.5 w-full rounded-lg border px-2 py-1 text-sm" /></label>)}
              </div>
              <button disabled={busy} onClick={() => run(() => call({ op: 'limits', patch: edit }), 'Limits saved')} className={`${BTN} mt-3`}>Save limits</button>
            </>
          )}
        </div>
        <div className="rounded-2xl border bg-white p-5">
          <h2 className="font-bold">Intake events (24 h)</h2>
          <ul className="mt-2 max-h-72 space-y-1 overflow-y-auto text-xs">
            {events.length === 0 && <li className="text-neutral-500">No intake events yet.</li>}
            {events.slice(0, 80).map((e, i) => <li key={i} className="border-b py-1"><span className="text-neutral-500">{new Date(e.created_at).toLocaleTimeString()}</span> <span className="font-semibold">{String(e.detail?.kind ?? e.event).replace(/_/g, ' ')}</span> {e.detail?.code ? <span className="text-red-700">{String(e.detail.code).replace(/_/g, ' ')}</span> : null} {e.username ?? ''} {e.ip ? <span className="font-mono text-neutral-500">{e.ip}</span> : null}</li>)}
          </ul>
        </div>
      </div>
    </div>
  )
}
