import { useState } from "react";
import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { toast } from "sonner";
import { AppShell, PageHeader } from "@/components/app-shell";
import { StatusPill } from "@/components/hub-dashboard";
import { Badge } from "@/components/ui/badge";
import { Button, goldPillClass } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { APPLICATION_KINDS, APPLICATION_STATUSES, STATUS_LABEL } from "@/lib/privileges";
import { bandLabel } from "@/lib/intern-match";
import { getShellMeta } from "@/lib/server/api-core";
import { getApplications, offerInternshipPath, setApplicationStatus, type HubApplication } from "@/lib/server/api-hub";
import { cn, formatDateTime } from "@/lib/utils";

export const Route = createFileRoute("/applications/")({
  validateSearch: (search: Record<string, unknown>) => ({
    kind: typeof search.kind === "string" ? search.kind : "all",
  }),
  loaderDeps: ({ search }) => ({ kind: search.kind }),
  loader: async ({ deps }) => {
    const [meta, apps] = await Promise.all([getShellMeta(), getApplications({ data: { kind: deps.kind } })]);
    return { meta, apps, kind: deps.kind };
  },
  component: ApplicationsPage,
});

function ApplicationsPage() {
  const { meta, apps, kind } = Route.useLoaderData();
  const router = useRouter();
  const kindLabel = APPLICATION_KINDS.find((k) => k.id === kind)?.label ?? "All applications";
  const internRows = apps.rows.filter((r) => r.kind === "internship");
  const otherRows = apps.rows.filter((r) => r.kind !== "internship");

  async function move(id: string, status: string) {
    const res = await setApplicationStatus({ data: { id, status } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success(`Moved to ${STATUS_LABEL[status] ?? status}`);
    await router.invalidate();
  }

  async function offer(id: string, path: "intern" | "fan" | "volunteer") {
    const res = await offerInternshipPath({ data: { id, path } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success(
      path === "intern" ? "Invited onto the strongest Handshake seat" : path === "fan" ? "Offered Fan — they stay in the league" : "Offered community outreach volunteer",
    );
    await router.invalidate();
  }

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker="Applications"
        title={kindLabel}
        description="Handshake internships are scored against all 11 open seats. A five-or-below intern score still qualifies as a Fan. Nobody walks away on a no-match letter."
      />
      <div className="mb-5 flex flex-wrap gap-2">
        <FilterChip to="/applications" search={{ kind: "all" }} active={kind === "all"} label="Inbox" />
        {APPLICATION_KINDS.map((k) => (
          <FilterChip
            key={k.id}
            to="/applications"
            search={{ kind: k.id }}
            active={kind === k.id}
            label={k.label}
          />
        ))}
      </div>

      {kind === "all" || kind === "internship" ? (
        <section className="mb-8">
          <p className="mb-3 text-[11px] font-medium tracking-[0.16em] text-muted-foreground uppercase">
            Handshake internships · 11 seats scored
          </p>
          <div className="grid gap-4">
            {internRows.map((row) => (
              <InternCard key={row.id} row={row} onMove={move} onOffer={offer} />
            ))}
            {internRows.length === 0 ? (
              <Card>
                <CardContent className="py-8 text-sm text-muted-foreground">No internship applications.</CardContent>
              </Card>
            ) : null}
          </div>
        </section>
      ) : null}

      {kind !== "internship" ? (
        <Card>
          <CardContent className="overflow-x-auto pt-5">
            <table className="w-full min-w-[52rem] text-left text-sm">
              <thead className="text-[11px] tracking-wide text-muted-foreground uppercase">
                <tr className="border-b border-border">
                  <th className="pb-2 font-medium">Applicant</th>
                  <th className="pb-2 font-medium">Kind</th>
                  <th className="pb-2 font-medium">Submitted</th>
                  <th className="pb-2 font-medium">Status</th>
                  <th className="pb-2 font-medium">Move</th>
                </tr>
              </thead>
              <tbody>
                {otherRows.map((row) => (
                  <tr key={row.id} className="border-b border-border/70 align-top">
                    <td className="py-3">
                      <p className="font-medium">{row.full_name}</p>
                      <p className="font-mono text-xs text-muted-foreground">{row.email}</p>
                      <p className="mt-1 max-w-md text-xs text-muted-foreground">{row.summary}</p>
                    </td>
                    <td className="py-3">
                      <Badge variant="outline">{row.kind}</Badge>
                    </td>
                    <td className="py-3 text-xs text-muted-foreground">{formatDateTime(row.submitted_at)}</td>
                    <td className="py-3">
                      <StatusPill status={row.status} />
                    </td>
                    <td className="py-3">
                      <div className="flex flex-wrap gap-1.5">
                        {APPLICATION_STATUSES.filter((s) => s !== row.status && s !== "offered_fan" && s !== "offered_volunteer").map(
                          (s) => (
                            <Button key={s} size="sm" variant={s === "declined" ? "outline" : "secondary"} onClick={() => void move(row.id, s)}>
                              {STATUS_LABEL[s]}
                            </Button>
                          ),
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
                {otherRows.length === 0 ? (
                  <tr>
                    <td className="py-8 text-sm text-muted-foreground" colSpan={5}>
                      No applications in this queue.
                    </td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </CardContent>
        </Card>
      ) : null}
    </AppShell>
  );
}

function InternCard({
  row,
  onMove,
  onOffer,
}: {
  row: HubApplication;
  onMove: (id: string, status: string) => Promise<void>;
  onOffer: (id: string, path: "intern" | "fan" | "volunteer") => Promise<void>;
}) {
  const [open, setOpen] = useState(false);
  const match = row.match;
  const best = match?.bestIntern;
  const offer = match?.offer;

  return (
    <Card>
      <CardContent className="p-5">
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <p className="font-display text-xl">{row.full_name}</p>
            <p className="font-mono text-xs text-muted-foreground">{row.email}</p>
            <p className="mt-2 max-w-2xl text-sm text-muted-foreground">{row.summary}</p>
          </div>
          <StatusPill status={row.status} />
        </div>

        {offer ? (
          <div className="mt-4 rounded-lg border border-primary/30 bg-primary/8 p-4">
            <p className="text-[11px] font-medium tracking-[0.16em] text-primary uppercase">Do not walk them away</p>
            <p className="mt-1 font-medium">
              {offer.path === "intern" ? `Invite to ${offer.title}` : offer.path === "volunteer" ? "Offer community outreach volunteer" : "They qualify as a CFL Fan"}
            </p>
            <p className="mt-1 text-sm text-muted-foreground">{offer.reason}</p>
          </div>
        ) : null}

        {match ? (
          <div className="mt-4 overflow-x-auto">
            <table className="w-full min-w-[40rem] text-left text-sm">
              <thead className="text-[11px] tracking-wide text-muted-foreground uppercase">
                <tr className="border-b border-border">
                  <th className="pb-2 font-medium">Handshake seat</th>
                  <th className="pb-2 font-medium">Coursework /40</th>
                  <th className="pb-2 font-medium">Core /25</th>
                  <th className="pb-2 font-medium">Bonus /10</th>
                  <th className="pb-2 font-medium">Experience /25</th>
                  <th className="pb-2 font-medium">Total</th>
                  <th className="pb-2 font-medium">Band</th>
                </tr>
              </thead>
              <tbody>
                {match.scores.map((s) => (
                  <tr
                    key={s.roleId}
                    className={cn("border-b border-border/60", best?.roleId === s.roleId && "bg-primary/8")}
                  >
                    <td className="py-2">
                      <p className="font-medium">{s.title}</p>
                      <p className="text-[11px] text-muted-foreground">
                        {s.handshakeId ? `#${s.handshakeId}` : ""} {s.track}
                      </p>
                    </td>
                    <td className="py-2 tabular">{s.coursework}</td>
                    <td className="py-2 tabular">{s.core}</td>
                    <td className="py-2 tabular">{s.bonus}</td>
                    <td className="py-2 tabular">{s.experience}</td>
                    <td className="py-2 tabular font-medium">{s.total}</td>
                    <td className="py-2">{bandLabel(s.band)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : null}

        <div className="mt-4 flex flex-wrap gap-2">
          <Button size="sm" variant="gold" onClick={() => void onOffer(row.id, "intern")}>
            Offer best Handshake seat
          </Button>
          <Button size="sm" variant="secondary" onClick={() => void onOffer(row.id, "fan")}>
            Offer Fan
          </Button>
          <Button size="sm" variant="secondary" onClick={() => void onOffer(row.id, "volunteer")}>
            Offer volunteer outreach
          </Button>
          {row.status !== "in_review" ? (
            <Button size="sm" variant="outline" onClick={() => void onMove(row.id, "in_review")}>
              In review
            </Button>
          ) : null}
          <Button size="sm" variant="outline" onClick={() => setOpen(true)}>
            Thank-you letter
          </Button>
        </div>

        <Dialog open={open} onOpenChange={setOpen}>
          <DialogContent
            title={`Thank you — ${row.full_name}`}
            description="Scored against all 11 Handshake seats. Copy this — never a no-match walk-away."
            className="max-h-[85vh] max-w-2xl overflow-y-auto"
          >
            <pre className="whitespace-pre-wrap rounded-lg bg-muted/40 p-4 text-sm leading-relaxed">
              {match?.letter ?? "Score this file first."}
            </pre>
            <div className="mt-4 flex justify-end gap-2">
              <Button
                variant="secondary"
                onClick={() => {
                  void navigator.clipboard.writeText(match?.letter ?? "");
                  toast.success("Letter copied");
                }}
              >
                Copy letter
              </Button>
              <Button onClick={() => setOpen(false)}>Close</Button>
            </div>
          </DialogContent>
        </Dialog>
      </CardContent>
    </Card>
  );
}

function FilterChip({
  to,
  search,
  active,
  label,
}: {
  to: "/applications";
  search: { kind: string };
  active: boolean;
  label: string;
}) {
  return (
    <Link
      to={to}
      search={search}
      className={goldPillClass(active)}
    >
      {label}
    </Link>
  );
}
