import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { useEffect, useState } 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 { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { NativeSelect } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { GEO_LABEL, NTEE_OPTIONS } from "@/lib/constants";
import type { Foundation } from "@/lib/types";
import { scoreUnscoredFoundations } from "@/lib/server/api-ai";
import { getAppSettings, getShellMeta } from "@/lib/server/api-core";
import { listFoundations } from "@/lib/server/api-foundations";
import { formatEin, money, pct } from "@/lib/utils";

export const Route = createFileRoute("/foundations/")({
  loader: async () => {
    const [meta, settings] = await Promise.all([getShellMeta(), getAppSettings()]);
    const foundations = await listFoundations({
      data: {
        threshold: settings.small_grant_threshold,
        minGrants: settings.min_grant_count,
        assetFloor: settings.asset_floor,
        assetCeiling: settings.asset_ceiling,
      },
    });
    return { meta, settings, foundations };
  },
  component: FoundationsPage,
});

function FoundationsPage() {
  const { meta, settings, foundations } = Route.useLoaderData();
  const router = useRouter();
  const [threshold, setThreshold] = useState(settings.small_grant_threshold);
  const [minGrants, setMinGrants] = useState(settings.min_grant_count);
  const [geo, setGeo] = useState("all");
  const [ntee, setNtee] = useState("all");
  const [rows, setRows] = useState<Foundation[]>(foundations);
  const [scoring, setScoring] = useState(false);

  useEffect(() => {
    let live = true;
    listFoundations({
      data: {
        threshold,
        minGrants,
        geo,
        ntee,
        assetFloor: settings.asset_floor,
        assetCeiling: settings.asset_ceiling,
      },
    }).then((next) => {
      if (live) setRows(next);
    });
    return () => {
      live = false;
    };
  }, [threshold, minGrants, geo, ntee, settings.asset_floor, settings.asset_ceiling]);

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker="Layer 2 · matched to CFL's mission"
        title="Family foundations"
        description="We read last year's 990 grant list — who they paid and for what — and score it against Capital Forge League: financial literacy, entrepreneurship education, veterans, college athletes, and the helmet screening platform. Grok adds a pursue / watch / skip brief. Nothing is mailed from this list."
        actions={
          <Button
            variant="outline"
            disabled={scoring}
            onClick={async () => {
              setScoring(true);
              try {
                const res = await scoreUnscoredFoundations({ data: { limit: 8 } });
                toast.message(`Grok scored ${res.scored} foundation${res.scored === 1 ? "" : "s"} against our mission`, {
                  description: res.errors[0]?.error ?? (res.available ? undefined : "Grok is not available — keyword match from the 990 list still applies."),
                });
                await router.invalidate();
                const next = await listFoundations({
                  data: {
                    threshold,
                    minGrants,
                    geo,
                    ntee,
                    assetFloor: settings.asset_floor,
                    assetCeiling: settings.asset_ceiling,
                  },
                });
                setRows(next);
              } catch (err) {
                toast.error(err instanceof Error ? err.message : "Score failed");
              } finally {
                setScoring(false);
              }
            }}
          >
            {scoring ? "Scoring…" : "Ask Grok: do they match us?"}
          </Button>
        }
      />

      <div className="mb-5 rounded-xl border border-border bg-card px-4 py-3 text-sm leading-relaxed">
        <p className="font-medium">How the match is built</p>
        <p className="mt-1 text-muted-foreground">
          Fit starts from their actual grants (veteran workshops, financial literacy, athlete rehab, helmet clinics), plus
          Florida-first geography and how often they make modest gifts. A high NTEE code alone is not enough — if they
          never paid an education or veteran grant, they rank lower.
        </p>
      </div>

      <div className="mb-5 grid gap-3 rounded-xl bg-card p-4 shadow-[var(--shadow-border)] sm:grid-cols-2 lg:grid-cols-4">
        <div className="flex flex-col gap-1.5">
          <Label>Small-grant threshold</Label>
          <NativeSelect value={threshold} onChange={(e) => setThreshold(Number(e.target.value))}>
            <option value={10000}>$10,000 (default)</option>
            <option value={25000}>$25,000 (secondary)</option>
          </NativeSelect>
        </div>
        <div className="flex flex-col gap-1.5">
          <Label>Minimum grants paid</Label>
          <NativeSelect value={minGrants} onChange={(e) => setMinGrants(Number(e.target.value))}>
            <option value={0}>Any</option>
            <option value={4}>4+</option>
            <option value={6}>6+</option>
            <option value={8}>8+</option>
          </NativeSelect>
        </div>
        <div className="flex flex-col gap-1.5">
          <Label>Geography</Label>
          <NativeSelect value={geo} onChange={(e) => setGeo(e.target.value)}>
            <option value="all">All tiers</option>
            <option value="fl">Florida first</option>
            <option value="southeast">Southeast</option>
            <option value="national">National</option>
          </NativeSelect>
        </div>
        <div className="flex flex-col gap-1.5">
          <Label>NTEE</Label>
          <NativeSelect value={ntee} onChange={(e) => setNtee(e.target.value)}>
            <option value="all">All aligned</option>
            {NTEE_OPTIONS.map((n) => (
              <option key={n.id} value={n.id}>
                {n.label}
              </option>
            ))}
          </NativeSelect>
        </div>
      </div>

      <div className="overflow-hidden rounded-xl bg-card shadow-[var(--shadow-border)]">
        <div className="overflow-x-auto">
        <table className="w-full min-w-[960px] 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">Foundation</th>
              <th className="px-4 py-3 font-semibold">Why they match CFL</th>
              <th className="px-4 py-3 font-semibold">Small-grant</th>
              <th className="px-4 py-3 font-semibold">Median</th>
              <th className="px-4 py-3 font-semibold">Mission fit</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((f) => (
              <tr key={f.id} className="border-b border-border last:border-0">
                <td className="px-4 py-3">
                  <Link to="/foundations/$id" params={{ id: f.id }} className="font-medium hover:text-primary">
                    {f.name}
                  </Link>
                  <p className="text-muted-foreground">
                    {f.city}, {f.state} · {formatEin(f.ein)} · {GEO_LABEL[f.geo_tier as keyof typeof GEO_LABEL] ?? f.geo_tier}
                  </p>
                  <p className="text-xs text-muted-foreground">
                    {f.ntee_label} · assets {money(f.assets, { compact: true })} · giving{" "}
                    {money(f.total_giving, { compact: true })}
                  </p>
                </td>
                <td className="px-4 py-3">
                  <PriorityBadge priority={f.ai_priority} importance={f.ai_importance} />
                  <div className="mt-1.5 flex flex-wrap gap-1">
                    {(f.mission_hits ?? []).slice(0, 4).map((h) => (
                      <Badge key={h} variant="muted">
                        {h}
                      </Badge>
                    ))}
                    {(f.mission_hits ?? []).length === 0 ? (
                      <span className="text-xs text-muted-foreground">
                        {f.grant_count === 0 ? "No grant list to read" : "No CFL keyword on last year's grants"}
                      </span>
                    ) : null}
                  </div>
                  {f.fit_reason ? <p className="mt-1 text-xs text-muted-foreground">{f.fit_reason}</p> : null}
                </td>
                <td className="px-4 py-3">
                  <p className="tabular font-medium">{pct(f.small_grant_ratio)}</p>
                  <p className="text-xs text-muted-foreground">
                    {f.grant_count} grants ≤ {money(threshold, { compact: true })} band
                  </p>
                </td>
                <td className="px-4 py-3 tabular">{money(f.median_grant)}</td>
                <td className="px-4 py-3">
                  <FitScore score={f.fit_score} />
                  {f.grant_count === 0 ? (
                    <Badge variant="warning" className="mt-1">
                      No grant list
                    </Badge>
                  ) : null}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </div>
    </AppShell>
  );
}
