import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { useState, type ReactNode } from "react";
import { toast } from "sonner";
import { AppShell, PageHeader } from "@/components/app-shell";
import { FitScore } from "@/components/fit-score";
import { PriorityBadge } from "@/components/priority-badge";
import { StageBadge } from "@/components/stage-badge";
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 { scoreFoundationWithGrok } from "@/lib/server/api-ai";
import { generateDraft } from "@/lib/server/api-drafts";
import { getFoundation } from "@/lib/server/api-foundations";
import { getShellMeta } from "@/lib/server/api-core";
import { identifyFoundation } from "@/lib/server/api-pipeline";
import { grantHitsMission } from "@/lib/scoring";
import { formatDate, formatEin, money, pct } from "@/lib/utils";

export const Route = createFileRoute("/foundations/$id")({
  loader: async ({ params }) => {
    const [meta, detail] = await Promise.all([getShellMeta(), getFoundation({ data: { id: params.id } })]);
    return { meta, detail };
  },
  component: FoundationDetail,
});

function FoundationDetail() {
  const { meta, detail } = Route.useLoaderData();
  const { foundation, grants, relationship, events, keywords } = detail;
  const router = useRouter();
  const [busy, setBusy] = useState(false);
  const [open, setOpen] = useState(false);

  if (!foundation) {
    return (
      <AppShell>
        <p>Foundation not found.</p>
      </AppShell>
    );
  }

  const fnd = foundation;

  async function identify() {
    setBusy(true);
    try {
      await identifyFoundation({ data: { foundationId: fnd.id } });
      toast.success("Marked Identified");
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Failed");
    } finally {
      setBusy(false);
    }
  }

  async function generate() {
    setBusy(true);
    try {
      const res = await generateDraft({ data: { foundationId: fnd.id, kind: "loi" } });
      setOpen(false);
      await router.navigate({ to: "/review/$id", params: { id: res.id } });
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Draft failed");
    } finally {
      setBusy(false);
    }
  }

  async function score() {
    setBusy(true);
    try {
      const res = await scoreFoundationWithGrok({ data: { foundationId: fnd.id, force: true } });
      toast.success(
        "priority" in res && res.priority ? `Grok: ${res.priority} · ${res.importance ?? ""}` : "Scored against CFL mission",
      );
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Score failed");
    } finally {
      setBusy(false);
    }
  }

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker={`${fnd.city}, ${fnd.state} · ${formatEin(fnd.ein)}`}
        title={fnd.name}
        description={fnd.fit_reason ?? fnd.ntee_label ?? "990-PF family foundation"}
        actions={
          <>
            <Button variant="outline" onClick={score} disabled={busy}>
              {busy ? "Scoring…" : "Score against our mission"}
            </Button>
            {relationship ? (
              <Button variant="outline" asChild>
                <Link to="/pipeline">Pipeline · {relationship.stage}</Link>
              </Button>
            ) : (
              <Button variant="outline" onClick={identify} disabled={busy}>
                Mark identified
              </Button>
            )}
            <Button onClick={() => setOpen(true)}>Draft LOI</Button>
          </>
        }
      />

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent title="Letter of inquiry" description="CFL voice. Human review required before send.">
          <Button disabled={busy} onClick={generate}>
            Generate LOI
          </Button>
        </DialogContent>
      </Dialog>

      <div className="mb-4 grid gap-3 sm:grid-cols-4">
        <Stat label="Mission fit" value={<FitScore score={fnd.fit_score} size="lg" />} />
        <Stat label="Small-grant ratio" value={pct(fnd.small_grant_ratio)} />
        <Stat label="Median grant" value={money(fnd.median_grant)} />
        <Stat label="Assets / giving" value={`${money(fnd.assets, { compact: true })} · ${money(fnd.total_giving, { compact: true })}`} />
      </div>

      <Card className="mb-4">
        <CardContent className="p-5">
          <div className="mb-2 flex flex-wrap items-center gap-2">
            <p className="text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Match to Capital Forge League</p>
            <PriorityBadge priority={fnd.ai_priority} importance={fnd.ai_importance} />
          </div>
          <div className="mb-2 flex flex-wrap gap-1">
            {(fnd.mission_hits ?? []).map((h) => (
              <Badge key={h} variant="muted">
                {h}
              </Badge>
            ))}
          </div>
          {fnd.ai_rationale ? (
            <p className="text-sm leading-relaxed">{fnd.ai_rationale}</p>
          ) : (
            <p className="text-sm text-muted-foreground">
              Keyword match uses last year's grants. Ask Grok to write a pursue / watch / skip brief against our mission.
            </p>
          )}
          {(fnd.ai_overlap ?? []).length > 0 ? (
            <ul className="mt-3 space-y-1 text-sm text-muted-foreground">
              {fnd.ai_overlap!.slice(0, 6).map((line) => (
                <li key={line}>· {line}</li>
              ))}
            </ul>
          ) : null}
        </CardContent>
      </Card>

      <div className="grid gap-4 lg:grid-cols-[1.2fr_0.8fr]">
        <Card>
          <CardContent className="p-5">
            <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">
              Grants they paid · {fnd.last_filing_year} · gold highlight matches CFL
            </p>
            {grants.length === 0 ? (
              <p className="text-sm text-muted-foreground">
                No computer-readable grant list on this filing. We can only score from their purpose code and geography
                until a grant list is available.
              </p>
            ) : (
              <div className="overflow-hidden rounded-lg">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="bg-primary text-left text-[11px] tracking-wider text-primary-foreground uppercase">
                      <th className="px-3 py-2 font-semibold">Recipient</th>
                      <th className="px-3 py-2 font-semibold">Purpose</th>
                      <th className="px-3 py-2 text-right font-semibold">Amount</th>
                    </tr>
                  </thead>
                  <tbody>
                    {grants.map((g) => {
                      const hit = grantHitsMission(g.recipient_name, g.purpose_raw, keywords ?? []);
                      return (
                        <tr key={g.id} className="border-t border-border">
                          <td className="py-2">
                            {g.recipient_name}
                            {hit ? (
                              <Badge variant="success" className="ml-2">
                                CFL match
                              </Badge>
                            ) : null}
                          </td>
                          <td className={hit ? "py-2 font-medium" : "py-2 text-muted-foreground"}>{g.purpose_raw}</td>
                          <td className="py-2 text-right tabular">{money(g.amount)}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )}
          </CardContent>
        </Card>
        <div className="flex flex-col gap-4">
          <Card>
            <CardContent className="p-5">
              <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Officers / trustees</p>
              {fnd.officers.length === 0 ? (
                <p className="text-sm text-muted-foreground">None listed.</p>
              ) : (
                <ul className="space-y-2 text-sm">
                  {fnd.officers.map((o) => (
                    <li key={o.name}>
                      <p className="font-medium">{o.name}</p>
                      <p className="text-muted-foreground">{o.title}</p>
                      {o.email ? <p className="text-xs text-muted-foreground">{o.email}</p> : null}
                    </li>
                  ))}
                </ul>
              )}
            </CardContent>
          </Card>
          <Card>
            <CardContent className="p-5">
              <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Relationship</p>
              {relationship ? (
                <div>
                  <StageBadge stage={relationship.stage} />
                  <p className="mt-2 text-sm">{relationship.next_action}</p>
                  <p className="text-xs text-muted-foreground">Due {formatDate(relationship.next_action_due)}</p>
                </div>
              ) : (
                <p className="text-sm text-muted-foreground">Not yet a pipeline target.</p>
              )}
            </CardContent>
          </Card>
          <Card>
            <CardContent className="p-5">
              <p className="mb-3 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Events</p>
              <ul className="space-y-2 text-sm">
                {events.map((e) => (
                  <li key={e.id}>
                    <span className="text-muted-foreground">{formatDate(e.created_at)}</span> · {e.event_type}
                    {e.notes ? <span className="text-muted-foreground"> — {e.notes}</span> : null}
                  </li>
                ))}
              </ul>
            </CardContent>
          </Card>
        </div>
      </div>
    </AppShell>
  );
}

function Stat({ label, value }: { label: string; value: ReactNode }) {
  return (
    <div className="rounded-xl bg-card p-4 shadow-[var(--shadow-border)]">
      <p className="text-[11px] tracking-[0.16em] text-muted-foreground uppercase">{label}</p>
      <div className="mt-1">{value}</div>
    </div>
  );
}
