"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState, useTransition } from "react";
import { Badge, Button, Card } from "@/components/ui";
import { decideApprovalAction } from "@/lib/actions/approvals";

export interface ApprovalItem { id: string; entryId: string; title: string; typeKey: string; typeLabel: string; exhibitorId: string | null; exhibitor: string; status: "PENDING" | "APPROVED" | "ACTION_REQUIRED" | "DECLINED"; comment: string; submittedAt: string }
const PER_PAGE = 10;
const STATUS_LABEL = { PENDING: "Awaiting approval", APPROVED: "Approved", ACTION_REQUIRED: "Action required", DECLINED: "Declined" } as const;
const TONE = { PENDING: "warning", APPROVED: "success", ACTION_REQUIRED: "info", DECLINED: "danger" } as const;
const selectCls = "rounded-md border border-border bg-card px-3 py-2 text-sm";

/** ShowOff "Approvals": submissions waiting for a decision, filterable by status, content type and exhibitor. */
export function ApprovalsTable({ siteId, base, rows, types, exhibitors }: { siteId: string; base: string; rows: ApprovalItem[]; types: { key: string; name: string }[]; exhibitors: { id: string; name: string }[] }) {
  const router = useRouter();
  const [status, setStatus] = useState<string>("PENDING");
  const [type, setType] = useState("");
  const [exhibitor, setExhibitor] = useState("");
  const [q, setQ] = useState("");
  const [page, setPage] = useState(0);
  const [open, setOpen] = useState<string | null>(null);
  const [comment, setComment] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [msg, setMsg] = useState<{ ok: boolean; text: string } | null>(null);
  const [pending, start] = useTransition();

  const filtered = rows.filter((r) => (!status || r.status === status) && (!type || r.typeKey === type) && (!exhibitor || r.exhibitorId === exhibitor) && r.title.toLowerCase().includes(q.toLowerCase()));
  const shown = filtered.slice(page * PER_PAGE, page * PER_PAGE + PER_PAGE);
  const reset = (f: () => void) => { f(); setPage(0); };

  function decide(id: string, decision: "approve" | "decline" | "action") {
    setError(null);
    start(async () => {
      const r = await decideApprovalAction(siteId, { id, decision, comment });
      if (!r.ok) { setError(r.fieldErrors?.comment ?? r.error); return; }
      setMsg({ ok: true, text: r.message ?? "Saved" }); setOpen(null); setComment(""); router.refresh();
    });
  }

  return (
    <>
      <p role="status" aria-live="polite" className={msg ? "mb-3 text-sm text-success" : "sr-only"}>{msg?.text}</p>
      <Card>
        <div className="flex flex-wrap items-center gap-2 border-b border-border p-3">
          <label htmlFor="ap-search" className="sr-only">Search approvals</label>
          <input id="ap-search" type="search" placeholder="Search…" className="w-full max-w-xs rounded-md border border-border bg-card px-3 py-2 text-sm sm:mr-auto" value={q} onChange={(e) => reset(() => setQ(e.target.value))} />
          <label className="sr-only" htmlFor="ap-status">Status</label>
          <select id="ap-status" className={selectCls} value={status} onChange={(e) => reset(() => setStatus(e.target.value))}>
            <option value="">Any Status</option>
            {(Object.keys(STATUS_LABEL) as (keyof typeof STATUS_LABEL)[]).map((s) => <option key={s} value={s}>{STATUS_LABEL[s]}</option>)}
          </select>
          <label className="sr-only" htmlFor="ap-type">Content type</label>
          <select id="ap-type" className={selectCls} value={type} onChange={(e) => reset(() => setType(e.target.value))}>
            <option value="">Any content type</option>
            {types.map((t) => <option key={t.key} value={t.key}>{t.name}</option>)}
          </select>
          <label className="sr-only" htmlFor="ap-ex">Exhibitor</label>
          <select id="ap-ex" className={selectCls} value={exhibitor} onChange={(e) => reset(() => setExhibitor(e.target.value))}>
            <option value="">Any exhibitor</option>
            {exhibitors.map((x) => <option key={x.id} value={x.id}>{x.name}</option>)}
          </select>
        </div>
        <table className="w-full text-left text-sm">
          <thead className="border-b border-border text-xs text-muted-foreground"><tr>{["Type", "Title", "Exhibitor", "Date added", "Status", "Moderation comments"].map((h) => <th key={h} scope="col" className="px-4 py-2 font-medium">{h}</th>)}<th scope="col" className="px-4 py-2"><span className="sr-only">Actions</span></th></tr></thead>
          <tbody className="divide-y divide-border">
            {shown.map((r) => (
              <tr key={r.id} className="align-top">
                <td className="px-4 py-3">{r.typeLabel}</td>
                <td className="px-4 py-3 font-medium"><Link className="text-primary underline" href={`${base.replace(/\/approvals$/, "")}/libraries/${r.typeKey}/${r.entryId}`}>{r.title}</Link></td>
                <td className="px-4 py-3 text-muted-foreground">{r.exhibitor}</td>
                <td className="px-4 py-3 text-muted-foreground">{new Date(r.submittedAt).toLocaleDateString("en-GB", { timeZone: "UTC", day: "numeric", month: "short", year: "numeric" })}</td>
                <td className="px-4 py-3"><Badge tone={TONE[r.status]}>{STATUS_LABEL[r.status]}</Badge></td>
                <td className="max-w-xs px-4 py-3 text-muted-foreground">{r.comment || "—"}</td>
                <td className="px-4 py-3 text-right">
                  {r.status === "PENDING" ? <Button variant="secondary" aria-expanded={open === r.id} onClick={() => { setOpen(open === r.id ? null : r.id); setComment(""); setError(null); }}>Review<span className="sr-only"> {r.title}</span></Button> : null}
                </td>
              </tr>
            )).flatMap((row, i) => {
              const r = shown[i]!;
              return open === r.id ? [row, (
                <tr key={`${r.id}-panel`} className="bg-muted/40">
                  <td colSpan={7} className="px-4 py-3">
                    <label htmlFor={`ap-c-${r.id}`} className="block text-xs font-medium">Moderation comment <span className="font-normal text-muted-foreground">(required to decline or ask for changes)</span></label>
                    <textarea id={`ap-c-${r.id}`} rows={2} maxLength={1000} className="mt-1 w-full max-w-xl rounded-md border border-border bg-card px-3 py-2 text-sm" value={comment} onChange={(e) => setComment(e.target.value)} aria-invalid={error ? true : undefined} aria-describedby={error ? `ap-e-${r.id}` : undefined} />
                    {error ? <p id={`ap-e-${r.id}`} role="alert" className="mt-1 text-xs text-danger">{error}</p> : null}
                    <div className="mt-2 flex flex-wrap gap-2">
                      <Button disabled={pending} onClick={() => decide(r.id, "approve")}>Approve and publish</Button>
                      <Button variant="secondary" disabled={pending} onClick={() => decide(r.id, "action")}>Action required</Button>
                      <Button variant="danger" disabled={pending} onClick={() => decide(r.id, "decline")}>Decline</Button>
                    </div>
                  </td>
                </tr>)] : [row];
            })}
            {shown.length === 0 ? <tr><td colSpan={7} className="px-4 py-8 text-center text-muted-foreground">{rows.length === 0 ? "Nothing has been submitted for approval yet." : "No data available in table"}</td></tr> : null}
          </tbody>
        </table>
        <div className="flex items-center justify-between border-t border-border p-3 text-xs text-muted-foreground">
          <span>{filtered.length ? `Showing ${page * PER_PAGE + 1} to ${Math.min(filtered.length, page * PER_PAGE + PER_PAGE)} of ${filtered.length} entries` : "Showing 0 to 0 of 0 entries"}</span>
          <span className="flex gap-1"><Button variant="secondary" disabled={page === 0} onClick={() => setPage((n) => n - 1)}>Previous</Button><Button variant="secondary" disabled={(page + 1) * PER_PAGE >= filtered.length} onClick={() => setPage((n) => n + 1)}>Next</Button></span>
        </div>
      </Card>
    </>
  );
}
