'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { GRANT_STATE_LABELS, grantState, surfaceByKey, type SurfaceKey } from '@/lib/domain/moderator-access'
import type { AccessLogRow, ModeratorGrant } from '@/lib/data/moderator-access'

/**
 * "Add moderator" on a moderator page (Nash, 2026-09-23): the admin types an
 * email, sends the invite, and that person can open this page and nothing
 * else. Only the admin sees this card; a moderator never invites anyone.
 */
const BTN = 'rounded-lg bg-[#0f1b2d] px-3 py-1.5 text-xs font-bold text-white transition hover:bg-[#1c2d47] disabled:opacity-50'
const BTN_SOFT = 'rounded-lg border bg-white px-3 py-1.5 text-xs font-bold text-neutral-800 transition hover:bg-neutral-50 disabled:opacity-50'
const BTN_DANGER = 'rounded-lg border border-red-200 bg-red-50 px-3 py-1.5 text-xs font-bold text-red-700 transition hover:bg-red-100 disabled:opacity-50'
const INPUT = 'rounded-lg border px-2.5 py-1.5 text-sm'

const TONE = { invited: 'bg-amber-50 text-amber-900 border-amber-200', active: 'bg-green-50 text-green-800 border-green-200', revoked: 'bg-neutral-100 text-neutral-600 border-neutral-200' }
const fmt = (iso: string | null | undefined) => (iso ? new Date(iso).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }) : '—')

export function ModeratorAccessCard({ surface, canManage }: { surface: SurfaceKey; canManage: boolean }) {
  const router = useRouter()
  const info = surfaceByKey(surface)
  const [open, setOpen] = useState(false)
  const [grants, setGrants] = useState<ModeratorGrant[] | null>(null)
  const [log, setLog] = useState<AccessLogRow[]>([])
  const [error, setError] = useState<string | null>(null)
  const [email, setEmail] = useState('')
  const [name, setName] = useState('')
  const [note, setNote] = useState('')
  const [busy, setBusy] = useState(false)

  useEffect(() => {
    if (!open || !canManage || surfaceByKey(surface)?.adminOnly) return
    let on = true
    fetch(`/api/admin/moderators?surface=${surface}`)
      .then(async (r) => ({ ok: r.ok, json: await r.json().catch(() => ({})) }))
      .then(({ ok, json }) => {
        if (!on) return
        if (!ok) { setError(json.error ?? 'Could not load who has access.'); setGrants([]); return }
        setError(null); setGrants(json.grants ?? []); setLog(json.log ?? [])
      })
    return () => { on = false }
  }, [open, canManage, surface])

  if (!canManage) return null
  // A page that can never be delegated says so instead of offering an invite box.
  if (info?.adminOnly) {
    return (
      <section className="rounded-2xl border bg-neutral-50 p-4">
        <h2 className="text-sm font-bold">Who can open this page</h2>
        <p className="text-xs text-neutral-500">The HeavyHaul Agent admin only. {info.label} hands out roles, passwords and multi-factor resets, so it is never delegated to a moderator. Every other moderator page can be.</p>
      </section>
    )
  }

  async function call(body: Record<string, unknown>, done: string) {
    setBusy(true)
    try {
      const r = await fetch('/api/admin/moderators', { 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.')
      toast.success(json.email_status === 'sent' || json.email_status === undefined ? done : `${done} The invitation email was ${String(json.email_status).replace(/_/g, ' ')}.`)
      const list = await fetch(`/api/admin/moderators?surface=${surface}`).then((x) => x.json()).catch(() => null)
      if (list) { setGrants(list.grants ?? []); setLog(list.log ?? []) }
      router.refresh()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : 'Something went wrong.')
    } finally {
      setBusy(false)
    }
  }

  const active = (grants ?? []).filter((g) => !g.revoked_at)
  return (
    <section className="rounded-2xl border bg-white p-4">
      <div className="flex flex-wrap items-center gap-2">
        <div>
          <h2 className="text-sm font-bold">Who can open this page</h2>
          <p className="text-xs text-neutral-500">{info?.description} Access is per page: a moderator you add here sees this page only.</p>
        </div>
        <button onClick={() => setOpen(!open)} className={`${BTN_SOFT} ml-auto`}>{open ? 'Hide' : `Manage access${active.length ? ` (${active.length})` : ''}`}</button>
      </div>

      {open && (
        <div className="mt-4 space-y-4">
          {error && <p className="rounded-lg bg-amber-50 p-3 text-xs text-amber-900">{error}</p>}

          <div className="flex flex-wrap items-end gap-2">
            <label className="text-xs font-semibold text-neutral-600">Email<input className={`${INPUT} mt-1 block w-60`} type="email" placeholder="person@company.com" value={email} onChange={(e) => setEmail(e.target.value)} /></label>
            <label className="text-xs font-semibold text-neutral-600">Name (optional)<input className={`${INPUT} mt-1 block w-44`} placeholder="Alex Marketing" value={name} onChange={(e) => setName(e.target.value)} /></label>
            <label className="text-xs font-semibold text-neutral-600">Note (optional)<input className={`${INPUT} mt-1 block w-56`} placeholder="Runs the Q4 outreach" value={note} onChange={(e) => setNote(e.target.value)} /></label>
            <button disabled={busy || !email.includes('@')} onClick={() => call({ op: 'grant', surface, email, name: name || undefined, note: note || undefined }, `${email.trim()} can now open this page.`).then(() => { setEmail(''); setName(''); setNote('') })} className={BTN}>
              {busy ? 'Sending…' : 'Add moderator & send invite'}
            </button>
          </div>
          <p className="text-[11px] text-neutral-500">They get an email with a link to this page. If they have no account yet, one is created the first time they sign in with that address.</p>

          {grants === null ? <p className="text-xs text-neutral-500">Loading…</p> : grants.length === 0 ? (
            <p className="text-xs text-neutral-500">Nobody has been given access to this page yet. You can always open it yourself.</p>
          ) : (
            <div className="overflow-x-auto rounded-xl border">
              <table className="w-full text-left text-xs">
                <thead className="bg-neutral-50 text-[10px] uppercase tracking-wide text-neutral-500">
                  <tr><th className="px-3 py-1.5">Person</th><th className="px-3 py-1.5">Status</th><th className="px-3 py-1.5">Given</th><th className="px-3 py-1.5">Last opened</th><th className="px-3 py-1.5">By</th><th className="px-3 py-1.5" /></tr>
                </thead>
                <tbody className="divide-y">
                  {grants.map((g) => {
                    const state = grantState(g)
                    return (
                      <tr key={g.id} className={g.revoked_at ? 'text-neutral-400' : ''}>
                        <td className="px-3 py-1.5"><span className="font-semibold">{g.name || g.email}</span><br /><span className="text-neutral-500">{g.email}</span>{g.note ? <><br /><span className="text-neutral-400">{g.note}</span></> : null}</td>
                        <td className="px-3 py-1.5"><span className={`inline-flex rounded-full border px-2 py-0.5 text-[10px] font-semibold ${TONE[state]}`}>{GRANT_STATE_LABELS[state]}</span></td>
                        <td className="px-3 py-1.5">{fmt(g.granted_at)}</td>
                        <td className="px-3 py-1.5">{fmt(g.last_access_at)}</td>
                        <td className="px-3 py-1.5">{g.revoked_at ? `revoked by ${g.revoked_by}` : g.granted_by}</td>
                        <td className="px-3 py-1.5 text-right">
                          {!g.revoked_at && (
                            <span className="flex justify-end gap-1.5">
                              {!g.accepted_at && <button disabled={busy} onClick={() => call({ op: 'reinvite', grant_id: g.id }, 'Invitation sent again.')} className={BTN_SOFT}>Resend</button>}
                              <button disabled={busy} onClick={() => { if (confirm(`Remove ${g.email}'s access to this page?`)) void call({ op: 'revoke', grant_id: g.id }, 'Access removed.') }} className={BTN_DANGER}>Remove</button>
                            </span>
                          )}
                        </td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>
          )}

          {log.length > 0 && (
            <details className="text-xs">
              <summary className="cursor-pointer font-semibold text-neutral-600">Access history ({log.length})</summary>
              <ul className="mt-1 space-y-0.5 text-neutral-500">
                {log.map((l) => <li key={l.id}>{fmt(l.created_at)} · {l.action} · {l.email_normalized} · by {l.actor_label}</li>)}
              </ul>
            </details>
          )}
        </div>
      )}
    </section>
  )
}
