import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { useState } from "react";
import { toast } from "sonner";
import { AppShell, PageHeader } from "@/components/app-shell";
import { Layer4PaymentsCard } from "@/components/layer-4-payments";
import { CflGiftTracking } from "@/components/cfl-gift-tracking";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Input, NativeSelect } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { TIER_LABEL, DONATIONS_MAILBOX } from "@/lib/constants";
import { getShellMeta } from "@/lib/server/api-core";
import {
  donationSummary,
  listDonations,
  listGiftTracking,
  simulateDonation,
  testSignedAccept,
  testUnsignedReject,
} from "@/lib/server/api-donations";
import { listRelationships } from "@/lib/server/api-pipeline";
import {
  ensureDonationReceipt,
  getReceipt,
  sendThankYou,
  setDonorEmail,
} from "@/lib/server/api-receipts";
import type { DonorReceipt } from "@/lib/types";
import { formatDate, moneyCents } from "@/lib/utils";

export const Route = createFileRoute("/donations/")({
  loader: async () => {
    const [meta, donations, summary, relationships, tracking] = await Promise.all([
      getShellMeta(),
      listDonations(),
      donationSummary(),
      listRelationships(),
      listGiftTracking(),
    ]);
    return { meta, donations, summary, relationships, tracking };
  },
  component: DonationsPage,
});

function DonationsPage() {
  const { meta, donations, summary, relationships, tracking } = Route.useLoaderData();
  const router = useRouter();
  const [donor, setDonor] = useState("Website visitor");
  const [email, setEmail] = useState("visitor@example.org");
  const [amount, setAmount] = useState("50");
  const [campaign, setCampaign] = useState("Open enrollment education");
  const [recurring, setRecurring] = useState(false);
  const [restricted, setRestricted] = useState(false);
  const [relId, setRelId] = useState("");
  const [receipt, setReceipt] = useState<DonorReceipt | null>(null);
  const [receiptOpen, setReceiptOpen] = useState(false);
  const [editEmail, setEditEmail] = useState("");
  const [polish, setPolish] = useState(false);
  const [busy, setBusy] = useState(false);

  async function simulate(e: React.FormEvent) {
    e.preventDefault();
    try {
      await simulateDonation({
        data: {
          donor_name: donor,
          donor_email: email || undefined,
          amount: Number(amount),
          campaign,
          recurring,
          restricted,
          relationshipId: relId || undefined,
        },
      });
      toast.success("Gift logged · official 501(c)(3) receipt queued");
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Failed");
    }
  }

  async function openReceipt(donationId: string) {
    setBusy(true);
    try {
      await ensureDonationReceipt({ data: { donationId } });
      const r = await getReceipt({ data: { donationId } });
      setReceipt(r);
      setEditEmail(r?.donor_email ?? "");
      setReceiptOpen(true);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Receipt failed");
    } finally {
      setBusy(false);
    }
  }

  async function send() {
    if (!receipt) return;
    setBusy(true);
    try {
      if (editEmail && editEmail !== receipt.donor_email) {
        await setDonorEmail({ data: { donationId: receipt.donation_id, donor_email: editEmail } });
      }
      const res = await sendThankYou({ data: { donationId: receipt.donation_id, polish } });
      toast.success(`Thank-you sent · ${res.receipt_no}`);
      setReceiptOpen(false);
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Send failed");
    } finally {
      setBusy(false);
    }
  }

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker="Layer 4 · inbound gifts"
        title="Donation activity"
        description="Layer 4 is money that arrived — DonorBox or a gift you logged. One receipt per gift. A foundation award letter is not a second payment."
        actions={
          <>
            <Button asChild variant="outline">
              <Link to="/agreements">Agreements</Link>
            </Button>
            <Button asChild variant="outline">
              <Link to="/donations/inbox">Open mailbox</Link>
            </Button>
          </>
        }
      />

      <Layer4PaymentsCard />
      <CflGiftTracking rows={tracking} />

      <Card className="mb-6">
        <CardContent className="flex flex-col gap-2 p-5 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <p className="text-[11px] tracking-[0.16em] text-muted-foreground uppercase">cPanel mailbox</p>
            <p className="mt-1 font-mono text-sm text-primary">{DONATIONS_MAILBOX}</p>
            <p className="text-xs text-muted-foreground">Thank-yous and receipts send from here. Forwards into Super Admin.</p>
          </div>
          <Button asChild>
            <Link to="/donations/inbox">View inbox</Link>
          </Button>
        </CardContent>
      </Card>

      <div className="mb-6 grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
        <Stat label="Total captured" value={moneyCents(summary.totalCents)} hint={`${summary.count} gifts`} />
        <Stat
          label="Recurring vs one-time"
          value={`${summary.recurring.count} / ${summary.onetime.count}`}
          hint={`${moneyCents(summary.recurring.cents)} recurring`}
        />
        <Stat
          label="Restricted vs open"
          value={`${summary.restricted.count} / ${summary.unrestricted.count}`}
          hint={`${moneyCents(summary.restricted.cents)} restricted`}
        />
        <Stat label="Campaigns" value={String(summary.campaigns.length)} hint="Category activity below" />
      </div>

      <div className="mb-6 grid gap-4 lg:grid-cols-2">
        <Card>
          <CardContent className="p-5">
            <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">By campaign</p>
            <ul className="space-y-2 text-sm">
              {summary.campaigns.map((c) => (
                <li key={c.name} className="flex justify-between gap-3">
                  <span>{c.name}</span>
                  <span className="tabular text-muted-foreground">
                    {c.count} · {moneyCents(c.cents)}
                  </span>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-5">
            <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">By amount tier</p>
            <ul className="space-y-2 text-sm">
              {summary.tiers.map((t) => (
                <li key={t.name} className="flex justify-between gap-3">
                  <span>{TIER_LABEL[t.name] ?? t.name}</span>
                  <span className="tabular text-muted-foreground">
                    {t.count} · {moneyCents(t.cents)}
                  </span>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>
      </div>

      <div className="mb-6 grid gap-4 lg:grid-cols-2">
        <Card>
          <CardContent className="p-5">
            <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Log inbound gift</p>
            <form className="flex flex-col gap-3" onSubmit={simulate}>
              <div className="grid gap-3 sm:grid-cols-2">
                <div className="flex flex-col gap-1.5">
                  <Label>Donor name</Label>
                  <Input value={donor} onChange={(e) => setDonor(e.target.value)} required />
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label>Donor email</Label>
                  <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
                </div>
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div className="flex flex-col gap-1.5">
                  <Label>Amount (USD)</Label>
                  <Input type="number" min="1" step="1" value={amount} onChange={(e) => setAmount(e.target.value)} />
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label>Campaign</Label>
                  <Input value={campaign} onChange={(e) => setCampaign(e.target.value)} />
                </div>
              </div>
              <div className="flex items-center justify-between">
                <Label>Recurring</Label>
                <Switch checked={recurring} onCheckedChange={setRecurring} />
              </div>
              <div className="flex items-center justify-between">
                <Label>Restricted</Label>
                <Switch checked={restricted} onCheckedChange={setRestricted} />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label>Link L3 relationship (optional)</Label>
                <NativeSelect value={relId} onChange={(e) => setRelId(e.target.value)}>
                  <option value="">None</option>
                  {relationships.map((r) => (
                    <option key={r.id} value={r.id}>
                      {r.foundation_name}
                    </option>
                  ))}
                </NativeSelect>
              </div>
              <Button type="submit">Record gift & issue receipt</Button>
            </form>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-5">
            <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Webhook signature</p>
            <p className="mb-4 text-sm text-muted-foreground">
              POST /api/webhooks/donorbox verifies HMAC-SHA256. An unsigned donation endpoint is a spoofing target.
            </p>
            <div className="flex flex-wrap gap-2">
              <Button
                variant="outline"
                onClick={async () => {
                  const r = await testUnsignedReject();
                  toast.message(r.accepted ? "Unexpected accept" : "Rejected unsigned payload — held in CFL gift tracking, not Layer 4");
                  await router.invalidate();
                }}
              >
                Send unsigned
              </Button>
              <Button
                onClick={async () => {
                  const r = await testSignedAccept({ data: {} });
                  toast.success(r.accepted ? "Signed payload accepted · receipt issued" : "Rejected");
                  await router.invalidate();
                }}
              >
                Send signed test
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>

      <div className="overflow-hidden rounded-xl bg-card shadow-[var(--shadow-border)]">
        <div className="overflow-x-auto">
        <table className="w-full min-w-[880px] text-left text-sm">
          <thead>
            <tr className="bg-primary text-[11px] tracking-wider text-primary-foreground uppercase">
              <th className="px-4 py-3 font-semibold">When</th>
              <th className="px-4 py-3 font-semibold">Donor</th>
              <th className="px-4 py-3 font-semibold">Campaign</th>
              <th className="px-4 py-3 font-semibold">Amount</th>
              <th className="px-4 py-3 font-semibold">Receipt</th>
              <th className="px-4 py-3 font-semibold">Thank-you</th>
            </tr>
          </thead>
          <tbody>
            {donations.map((d) => (
              <tr key={d.id} className="border-b border-border last:border-0">
                <td className="px-4 py-3">{formatDate(d.received_at)}</td>
                <td className="px-4 py-3">
                  {d.donor_name}
                  {d.donor_email ? <p className="font-mono text-xs text-muted-foreground">{d.donor_email}</p> : null}
                  {d.relationship_foundation ? (
                    <p className="text-xs text-muted-foreground">
                      Linked ·{" "}
                      <Link to="/pipeline" className="text-primary hover:underline">
                        {d.relationship_foundation}
                      </Link>
                    </p>
                  ) : null}
                </td>
                <td className="px-4 py-3">{d.campaign}</td>
                <td className="px-4 py-3 tabular">{moneyCents(d.amount_cents)}</td>
                <td className="px-4 py-3">
                  <div className="flex flex-col items-start gap-1.5">
                    {d.receipt_no ? (
                      <span className="font-mono text-xs">{d.receipt_no}</span>
                    ) : (
                      <Badge variant="outline">Queued</Badge>
                    )}
                    <Button size="sm" variant="outline" disabled={busy} onClick={() => openReceipt(d.id)}>
                      View receipt
                    </Button>
                  </div>
                </td>
                <td className="px-4 py-3">
                  {d.thankyou_sent_at ? (
                    <Badge variant="success">Sent {formatDate(d.thankyou_sent_at)}</Badge>
                  ) : (
                    <Button size="sm" disabled={busy} onClick={() => openReceipt(d.id)}>
                      Send thank-you
                    </Button>
                  )}
                  <div className="mt-1.5 flex flex-wrap gap-1">
                    <Badge variant="muted">{TIER_LABEL[d.amount_tier] ?? d.amount_tier}</Badge>
                    {d.recurring ? <Badge>Recurring</Badge> : null}
                    {d.restricted ? <Badge variant="warning">Restricted</Badge> : null}
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </div>

      <Dialog open={receiptOpen} onOpenChange={setReceiptOpen}>
        <DialogContent
          className="max-h-[90vh] max-w-2xl overflow-y-auto"
          title={receipt ? `Receipt ${receipt.receipt_no}` : "Receipt"}
          description="Official contemporaneous written acknowledgment. Thank-you sends from donations@ with this receipt attached."
        >
          {receipt ? (
            <div className="flex flex-col gap-4">
              <div className="flex flex-col gap-1.5">
                <Label htmlFor="rcpt-email">Donor email</Label>
                <Input
                  id="rcpt-email"
                  type="email"
                  value={editEmail}
                  onChange={(e) => setEditEmail(e.target.value)}
                  placeholder="Required to send"
                />
              </div>
              <div>
                <p className="mb-2 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Official receipt</p>
                <pre className="max-h-56 overflow-auto whitespace-pre-wrap rounded-lg bg-muted/40 p-3 font-mono text-xs leading-relaxed">
                  {receipt.body_text}
                </pre>
              </div>
              <div>
                <p className="mb-2 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Thank-you</p>
                <pre className="max-h-40 overflow-auto whitespace-pre-wrap rounded-lg bg-muted/40 p-3 font-mono text-xs leading-relaxed">
                  {receipt.thankyou_text}
                </pre>
              </div>
              <label className="flex min-h-11 items-center gap-2 text-sm">
                <input type="checkbox" checked={polish} onChange={(e) => setPolish(e.target.checked)} />
                Polish the thank-you with Grok before sending
              </label>
              <div className="flex flex-wrap gap-2">
                <Button onClick={send} disabled={busy || receipt.status === "sent"}>
                  {receipt.status === "sent" ? "Already sent" : busy ? "Sending…" : "Send thank-you & receipt"}
                </Button>
                <Button variant="outline" asChild>
                  <Link to="/agreements">Draft agreement</Link>
                </Button>
              </div>
            </div>
          ) : null}
        </DialogContent>
      </Dialog>
    </AppShell>
  );
}

function Stat({ label, value, hint }: { label: string; value: string; hint: string }) {
  return (
    <Card>
      <CardContent className="p-4">
        <p className="text-[11px] tracking-[0.16em] text-muted-foreground uppercase">{label}</p>
        <p className="mt-1 font-display text-2xl">{value}</p>
        <p className="text-xs text-muted-foreground">{hint}</p>
      </CardContent>
    </Card>
  );
}
