import { useEffect, useState } from "react";
import {
  Check,
  Download,
  Eye,
  EyeOff,
  FileText,
  Flag,
  Lock,
  MessageCircle,
  Radio,
  Shield,
  Sparkles,
  Upload,
} from "lucide-react";
import { toast } from "sonner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input, Textarea } from "@/components/ui/input";
import {
  adoptDealDoc,
  answerDealQuestion,
  bringDealLive,
  downloadDealDoc,
  getDealRoom,
  postDealQuestion,
  requestDealDocs,
  reviewDealDoc,
  uploadDealDoc,
  type DealAccess,
  type DealDoc,
  type DealQuestion,
} from "@/lib/server/api-stadium";
import { enhanceDealPacket } from "@/lib/server/api-ai";
import { canDownloadDoc } from "@/lib/deal-access";
import { EVENT_CATALOG, type DealEventType } from "@/lib/stadium-scoring";
import { DEAL_ROOM_COURSE, DEAL_ROOM_NAV } from "@/lib/deal-room-sections";
import { pingStadiumLive } from "@/lib/stadium-live";
import { useRoleStore } from "@/lib/role-store";
import { formatDateTime } from "@/lib/utils";
import { cn } from "@/lib/utils";

const DOC_KINDS: { id: DealEventType; label: string; blurb: string }[] = [
  { id: "exec_summary", label: "Executive summary", blurb: "The one-pager a donor reads first." },
  { id: "business_plan", label: "Business plan", blurb: "Problem, market, and how the studio works." },
  { id: "financials", label: "Financial packet", blurb: "Budget band. No invented forecasts." },
  { id: "packet_section", label: "Packet section", blurb: "Any other desk filing." },
];

type Room = Awaited<ReturnType<typeof getDealRoom>>;
type ReviewDraft = { enhanced: string; notes: string; findings: string[]; model: string; available: boolean };

/** Stay on this desk. Navigating to /capstone was bouncing the page shut. */
export function OpenDealRoom({
  slug,
  label,
}: {
  slug: string;
  label?: string;
}) {
  const [open, setOpen] = useState(false);
  return (
    <div className="mt-3">
      <Button type="button" variant="gold" size="lg" className="deal-cta" onClick={() => setOpen((v) => !v)}>
        <Flag className="size-4" />
        {open ? "Close deal room" : (label ?? "Open the deal room")}
      </Button>
      {open ? (
        <div className="mt-4">
          <DealRoomPanel slug={slug} />
        </div>
      ) : null}
    </div>
  );
}

function identity() {
  const s = useRoleStore.getState();
  return { email: s.email, role: s.role, signedIn: s.signedIn };
}

export function DealRoomPanel({ slug }: { slug: string }) {
  const email = useRoleStore((s) => s.email);
  const role = useRoleStore((s) => s.role);
  const signedIn = useRoleStore((s) => s.signedIn);
  const account = useRoleStore((s) => s.account());
  const [room, setRoom] = useState<Room | null>(null);
  const [busy, setBusy] = useState(false);

  async function load() {
    const next = await getDealRoom({ data: { slug, email, role, signedIn } });
    setRoom(next);
  }

  useEffect(() => {
    let live = true;
    void getDealRoom({ data: { slug, email, role, signedIn } }).then((d) => {
      if (live) setRoom(d);
    });
    return () => {
      live = false;
    };
  }, [slug, email, role, signedIn]);

  async function requestPacket() {
    setBusy(true);
    try {
      const res = await requestDealDocs({ data: { slug, ...identity() } });
      toast.success(`Packet requested · ${res.points} yards. The ball moved.`);
      pingStadiumLive();
      await load();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not request the packet.");
    } finally {
      setBusy(false);
    }
  }

  async function goLive() {
    setBusy(true);
    try {
      const res = await bringDealLive({ data: { slug, ...identity() } });
      toast.success(`Brought live · ${res.points} yards${res.bonus ? ` + ${res.bonus} loaded-packet` : ""}.`);
      pingStadiumLive();
      await load();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not bring the packet live.");
    } finally {
      setBusy(false);
    }
  }

  if (!room) {
    return (
      <Card>
        <CardContent className="pt-5">
          <p className="text-sm text-muted-foreground">Opening the deal room…</p>
        </CardContent>
      </Card>
    );
  }

  const { access, docs, questions, project, packet, sections, aiEnabled } = room;

  return (
    <div className="space-y-4">
      <Card>
        <CardContent className="pt-5">
          <div className="mb-3 flex flex-wrap items-center justify-between gap-3">
            <div>
              <p className="text-[11px] font-medium tracking-[0.16em] text-primary uppercase">Deal room</p>
              <h2 className="font-display text-xl">{project?.title ?? "Studio packet"}</h2>
            </div>
            <div className="flex flex-wrap items-center justify-end gap-1.5">
              {packet.live ? <Badge variant="success">Live</Badge> : <Badge variant="muted">Assembling</Badge>}
              {packet.loaded ? <Badge variant="outline">Packet loaded</Badge> : null}
              {aiEnabled && access.seeOriginal ? <Badge variant="default">Numbers reviewed</Badge> : null}
              <Badge variant={access.view ? "success" : "muted"}>{access.label}</Badge>
            </div>
          </div>
          <p className="text-sm font-medium text-navy">{access.reason}</p>
          {access.seeOriginal ? (
            <p className="mt-2 text-sm text-navy">
              Filing exec + plan + financials banks a 24-yard loaded-packet bonus. Bringing it live is 32 yards.
            </p>
          ) : access.request ? (
            <p className="mt-2 text-sm text-navy">
              This is a request to the studio team — it is not the deal room. If you request the packet, the team
              receives <strong>16 yards</strong> and a scoring bonus on the Sweet 16 board.
            </p>
          ) : null}
          {access.seeOriginal ? <PacketReviewNote /> : null}
          {access.upload || access.goLive ? <AccessMatrix access={access} /> : null}
          <div className="mt-4 flex flex-wrap gap-2">
            {access.request && !packet.requested ? (
              <div className="w-full space-y-2">
                <Button
                  size="lg"
                  variant="gold"
                  className="deal-cta"
                  disabled={busy}
                  onClick={() => void requestPacket()}
                >
                  <Flag className="size-4" />
                  Request the packet from the team
                </Button>
                <p className="text-sm font-medium text-navy">
                  The team will receive 16 yards and a scoring bonus. You are asking the students for documents — you are
                  not opening their deal room.
                </p>
              </div>
            ) : null}
            {access.request && packet.requested ? (
              <p className="self-center text-xs text-muted-foreground">Request is in. The studio has your ask.</p>
            ) : null}
            {access.goLive && !packet.live ? (
              <Button size="lg" variant="navy" className="deal-cta" disabled={busy} onClick={() => void goLive()}>
                <Radio className="size-4" />
                Bring live · 32 yards
              </Button>
            ) : null}
          </div>
          {!access.view ? (
            <p className="mt-4 flex items-start gap-2 rounded-lg bg-muted px-3 py-3 text-sm text-muted-foreground">
              <EyeOff className="mt-0.5 size-4 shrink-0" />
              Packets stay off the public site. Requesting them still moves the Sweet 16 ball.
            </p>
          ) : null}
        </CardContent>
      </Card>

      {access.view ? <DealRoomContents sections={sections ?? {}} docs={docs} /> : null}

      {access.view ? (
        <Card>
          <CardContent className="pt-5">
            <p className="mb-3 text-[11px] font-medium tracking-[0.16em] text-muted-foreground uppercase">Documents</p>
            <ul className="space-y-3">
              {docs.map((doc) => (
                <DocRow
                  key={doc.id}
                  doc={doc}
                  access={access}
                  email={email}
                  role={role}
                  signedIn={signedIn}
                  aiEnabled={aiEnabled}
                  onDone={load}
                />
              ))}
              {docs.length === 0 ? <li className="text-sm text-muted-foreground">No packets filed yet.</li> : null}
            </ul>
            {access.upload ? (
              <UploadForm slug={slug} aiEnabled={aiEnabled} onDone={load} />
            ) : (
              <p className="mt-4 flex items-center gap-2 text-xs text-muted-foreground">
                <Lock className="size-3.5" />
                Only the studio team and coaches can file new packets.
              </p>
            )}
          </CardContent>
        </Card>
      ) : null}

      <Card>
        <CardContent className="pt-5">
          <div className="mb-3 flex items-center gap-2">
            <MessageCircle className="size-4 text-primary" />
            <h3 className="font-display text-lg">Questions</h3>
          </div>
          {access.seeQuestions ? (
            <ul className="space-y-4">
              {questions.map((q) => (
                <QuestionRow key={q.id} q={q} canAnswer={access.answer} slug={slug} onDone={load} />
              ))}
              {questions.length === 0 ? <li className="text-sm text-muted-foreground">No questions yet.</li> : null}
            </ul>
          ) : (
            <p className="text-sm text-muted-foreground">
              Question threads sit with the studio.{" "}
              {access.ask
                ? "Leave one below — the team sees it on their desk. You will not see the thread."
                : "You cannot read or post here."}
            </p>
          )}
          {access.ask ? (
            <AskForm
              slug={slug}
              email={email}
              name={account.name}
              role={role}
              signedIn={signedIn}
              busy={busy}
              setBusy={setBusy}
              onDone={load}
            />
          ) : null}
        </CardContent>
      </Card>
    </div>
  );
}

function DealRoomContents({
  sections,
  docs,
}: {
  sections: Record<string, string>;
  docs: DealDoc[];
}) {
  const [active, setActive] = useState(DEAL_ROOM_NAV[0]?.id ?? "summary");
  const item = DEAL_ROOM_NAV.find((n) => n.id === active) ?? DEAL_ROOM_NAV[0];
  const body = item?.packetKey ? sections[item.packetKey]?.trim() : "";
  const filed = docs.length;

  return (
    <Card>
      <CardContent className="pt-5">
        <p className="text-[11px] font-medium tracking-[0.16em] text-primary uppercase">
          {DEAL_ROOM_COURSE.code} · {DEAL_ROOM_COURSE.title}
        </p>
        <p className="mt-1 text-sm text-navy">{DEAL_ROOM_COURSE.summary}</p>
        <div className="mt-4 grid gap-4 lg:grid-cols-[16rem_1fr]">
          <nav className="max-h-[28rem] overflow-y-auto rounded-lg bg-muted/70 p-2">
            <p className="px-2 py-1 text-[11px] font-semibold tracking-wide text-navy uppercase">Deal room content</p>
            {DEAL_ROOM_NAV.map((n) => {
              const filled = n.packetKey ? Boolean(sections[n.packetKey]?.trim()) : n.kind === "docs" && filed > 0;
              return (
                <button
                  key={n.id}
                  type="button"
                  onClick={() => setActive(n.id)}
                  className={cn(
                    "flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-left text-sm",
                    active === n.id ? "bg-primary text-primary-foreground" : "text-navy hover:bg-card",
                  )}
                >
                  <span>{n.label}</span>
                  {filled ? <Check className="size-3.5 shrink-0" /> : null}
                </button>
              );
            })}
          </nav>
          <div>
            <h3 className="font-display text-xl">{item?.label}</h3>
            <p className="mt-1 text-sm text-navy">{item?.curriculum}</p>
            {body ? (
              <p className="mt-3 whitespace-pre-wrap text-sm text-navy">{body}</p>
            ) : item?.kind === "docs" ? (
              <p className="mt-3 text-sm text-navy">
                {filed ? `${filed} filed packet${filed === 1 ? "" : "s"} below.` : "No documents filed yet. Students file exec, plan, and financials here."}
              </p>
            ) : (
              <p className="mt-3 text-sm text-navy">
                Not filed yet. Students and coaches fill this section as part of {DEAL_ROOM_COURSE.code}. Donors see it
                when the packet is live. This is a donation briefing — never an investment.
              </p>
            )}
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

function AccessMatrix({ access }: { access: DealAccess }) {
  const rows: { label: string; on: boolean }[] = [
    { label: "View packet", on: access.view },
    { label: "Download", on: access.download },
    { label: "Financials download", on: access.downloadFinancials },
    { label: "File a packet", on: access.upload },
    { label: "Request docs", on: access.request },
    { label: "Bring live", on: access.goLive },
    { label: "Ask", on: access.ask },
    { label: "Answer", on: access.answer },
  ];
  return (
    <ul className="mt-4 grid grid-cols-2 gap-1.5 sm:grid-cols-4">
      {rows.map((r) => (
        <li
          key={r.label}
          className={cn(
            "flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-sm font-semibold text-navy",
            r.on ? "bg-primary/25" : "bg-muted",
          )}
        >
          {r.on ? <Eye className="size-3.5 shrink-0 text-navy" /> : <Shield className="size-3.5 shrink-0 text-navy" />}
          {r.label}
        </li>
      ))}
    </ul>
  );
}

function DocRow({
  doc,
  access,
  email,
  role,
  signedIn,
  aiEnabled,
  onDone,
}: {
  doc: DealDoc;
  access: DealAccess;
  email: string;
  role: string;
  signedIn: boolean;
  aiEnabled: boolean;
  onDone: () => Promise<void>;
}) {
  const spec = EVENT_CATALOG[doc.kind as DealEventType];
  const canDl = canDownloadDoc(access, doc.kind);
  const [pane, setPane] = useState<"published" | "original" | "ai">("published");
  const [busy, setBusy] = useState<"review" | "adopt-ai" | "adopt-original" | null>(null);

  const original = doc.original_body || doc.body;
  const showCompare = access.seeOriginal && (Boolean(doc.ai_body) || doc.used_ai);

  async function save() {
    try {
      const file = await downloadDealDoc({ data: { docId: doc.id, email, role, signedIn } });
      const blob = new Blob([file.body], { type: "text/plain;charset=utf-8" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${file.title.replaceAll(" ", "-").toLowerCase()}.txt`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Download blocked.");
    }
  }

  async function review() {
    setBusy("review");
    try {
      const res = await reviewDealDoc({ data: { docId: doc.id, ...identity() } });
      toast.success(res.available === false ? "Offline review saved. Original kept." : "Grok reviewed this packet. Original kept.");
      setPane("ai");
      await onDone();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Grok could not review this packet.");
    } finally {
      setBusy(null);
    }
  }

  async function adopt(use: "original" | "ai") {
    setBusy(use === "ai" ? "adopt-ai" : "adopt-original");
    try {
      await adoptDealDoc({ data: { docId: doc.id, use, ...identity() } });
      toast.success(use === "ai" ? "Donor copy is now the Grok-enhanced version. Coach can still see the original." : "Published copy is the student original.");
      setPane("published");
      await onDone();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not switch the published copy.");
    } finally {
      setBusy(null);
    }
  }

  const shown =
    pane === "original" ? original : pane === "ai" ? (doc.ai_body ?? original) : doc.body;

  return (
    <li className={cn("relative overflow-hidden rounded-xl border border-border p-4", !canDl && "deal-viewonly")}>
      {!canDl ? <span className="deal-watermark">View only · no download</span> : null}
      <div className="flex flex-wrap items-start justify-between gap-2">
        <div>
          <p className="text-sm font-semibold">{doc.title}</p>
          <p className="text-xs text-muted-foreground">
            {spec?.label ?? doc.kind} · {doc.uploaded_by} · {formatDateTime(doc.created_at)}
            {spec ? ` · ${spec.points} yards` : null}
          </p>
        </div>
        <div className="flex flex-wrap items-center gap-1.5">
          {doc.used_ai && access.seeOriginal ? (
            <Badge variant="warning">Enhanced donor copy</Badge>
          ) : access.seeOriginal ? (
            <Badge variant="outline">Student original</Badge>
          ) : null}
          {doc.ai_body && !doc.used_ai && access.seeOriginal ? <Badge variant="muted">Review draft on file</Badge> : null}
          {canDl ? (
            <Button size="sm" variant="outline" onClick={() => void save()}>
              <Download className="size-3.5" />
              Download
            </Button>
          ) : (
            <Badge variant="muted">View only</Badge>
          )}
        </div>
      </div>

      {showCompare ? (
        <div className="mt-3 flex flex-wrap gap-1.5">
          <Button size="sm" variant={pane === "published" ? "gold" : "outline"} onClick={() => setPane("published")}>
            Published
          </Button>
          <Button size="sm" variant={pane === "original" ? "gold" : "outline"} onClick={() => setPane("original")}>
            Student original
          </Button>
          {doc.ai_body ? (
            <Button size="sm" variant={pane === "ai" ? "gold" : "outline"} onClick={() => setPane("ai")}>
              Numbers-checked copy
            </Button>
          ) : null}
        </div>
      ) : null}

      <p className={cn("mt-3 text-sm leading-relaxed whitespace-pre-wrap", !canDl && "select-none")}>{shown}</p>

      {access.seeOriginal && pane === "ai" && doc.ai_notes ? (
        <p className="mt-3 rounded-lg bg-muted px-3 py-2 text-xs leading-relaxed text-muted-foreground whitespace-pre-wrap">
          {doc.ai_notes}
        </p>
      ) : null}

      {access.upload ? (
        <div className="mt-3 flex flex-wrap gap-2">
          {aiEnabled && !doc.ai_body ? (
            <Button size="sm" variant="outline" disabled={busy !== null} onClick={() => void review()}>
              <Sparkles className="size-3.5" />
              {busy === "review" ? "Grok is reading…" : "Ask Grok to review"}
            </Button>
          ) : null}
          {aiEnabled && doc.ai_body && !doc.used_ai ? (
            <Button size="sm" variant="gold" disabled={busy !== null} onClick={() => void adopt("ai")}>
              <Check className="size-3.5" />
              {busy === "adopt-ai" ? "Switching…" : "Publish numbers-checked copy"}
            </Button>
          ) : null}
          {doc.used_ai ? (
            <Button size="sm" variant="outline" disabled={busy !== null} onClick={() => void adopt("original")}>
              {busy === "adopt-original" ? "Switching…" : "Revert to student original"}
            </Button>
          ) : null}
        </div>
      ) : null}
    </li>
  );
}

function UploadForm({
  slug,
  aiEnabled,
  onDone,
}: {
  slug: string;
  aiEnabled: boolean;
  onDone: () => Promise<void>;
}) {
  const [kind, setKind] = useState<DealEventType>("exec_summary");
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");
  const [review, setReview] = useState<ReviewDraft | null>(null);
  const [useAi, setUseAi] = useState(false);
  const [busy, setBusy] = useState<"file" | "grok" | null>(null);

  function reset() {
    setTitle("");
    setBody("");
    setReview(null);
    setUseAi(false);
  }

  async function onFile(file: File | undefined) {
    if (!file) return;
    const text = await file.text();
    if (!title.trim()) setTitle(file.name.replace(/\.[^.]+$/, "").replaceAll("-", " "));
    setBody(text.trim());
    setReview(null);
    setUseAi(false);
  }

  async function grok() {
    if (title.trim().length < 4 || body.trim().length < 12) {
      toast.error("Give Grok a title and a real paragraph.");
      return;
    }
    setBusy("grok");
    try {
      const res = await enhanceDealPacket({ data: { kind, title: title.trim(), body: body.trim() } });
      setReview({
        enhanced: res.enhanced,
        notes: res.notes,
        findings: res.findings,
        model: res.model,
        available: res.available,
      });
      setUseAi(false);
      toast.success(
        res.available
          ? "Grok reviewed the packet. Original is saved. Choose which copy to publish."
          : "Offline review ready. Original is still yours.",
      );
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Grok could not review this packet.");
    } finally {
      setBusy(null);
    }
  }

  async function submit() {
    if (title.trim().length < 4 || body.trim().length < 12) {
      toast.error("Give the packet a title and a real paragraph.");
      return;
    }
    setBusy("file");
    try {
      const res = await uploadDealDoc({
        data: {
          slug,
          ...identity(),
          kind,
          title: title.trim(),
          body: body.trim(),
          aiBody: review?.enhanced,
          aiNotes: review ? `${review.notes}\n\n${review.findings.map((f) => `• ${f}`).join("\n")}`.trim() : undefined,
          useAi: Boolean(useAi && review?.enhanced),
          aiModel: review?.model,
        },
      });
      pingStadiumLive();
      toast.success(
        `${EVENT_CATALOG[kind].label} · ${res.points} yards${res.bonus ? ` + ${res.bonus} loaded-packet bonus` : ""}${res.usedAi ? " · Grok-enhanced donor copy" : " · student original"}.`,
      );
      reset();
      await onDone();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not file the packet.");
    } finally {
      setBusy(null);
    }
  }

  return (
    <div className="mt-5 border-t border-border pt-4">
      <p className="mb-2 text-[11px] font-medium tracking-[0.16em] text-muted-foreground uppercase">File a packet</p>
      <p className="mb-3 text-sm text-muted-foreground">
        Your original is always kept. Grok can catch donor-facing mistakes — invented numbers, medical claims, equity
        language — then you choose whether donors see the enhanced copy. Your coach sees both.
      </p>
      <div className="grid gap-2 sm:grid-cols-2">
        {DOC_KINDS.map((k) => {
          const on = kind === k.id;
          return (
            <button
              key={k.id}
              type="button"
              onClick={() => {
                setKind(k.id);
                setReview(null);
                setUseAi(false);
              }}
              className={cn(
                "rounded-xl border px-3 py-3 text-left transition-colors",
                on ? "border-primary bg-primary/10" : "border-border bg-card hover:border-primary/40",
              )}
            >
              <p className="text-sm font-semibold">{k.label}</p>
              <p className="mt-0.5 text-xs text-muted-foreground">{k.blurb}</p>
              <p className="mt-1 text-[11px] font-medium tracking-wide text-primary uppercase">
                {EVENT_CATALOG[k.id].points} yards
              </p>
            </button>
          );
        })}
      </div>
      <div className="mt-3 grid gap-2 sm:grid-cols-2">
        <Input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Document title" />
        <label className="flex h-10 cursor-pointer items-center justify-center gap-2 rounded-md border border-dashed border-primary/40 bg-primary/5 px-3 text-sm font-medium text-primary hover:bg-primary/10">
          <FileText className="size-4" />
          Attach text file
          <input
            type="file"
            accept=".txt,.md,.csv,text/plain"
            className="sr-only"
            onChange={(e) => void onFile(e.target.files?.[0])}
          />
        </label>
      </div>
      <Textarea
        className="mt-2 min-h-32"
        value={body}
        onChange={(e) => {
          setBody(e.target.value);
          setReview(null);
          setUseAi(false);
        }}
        placeholder="Write the packet a donor would read. Numbers must be yours — Grok will not invent them."
      />

      {review ? (
        <div className="mt-3 grid gap-3 lg:grid-cols-2">
          <div className="rounded-xl border border-border p-3">
            <p className="text-[11px] font-medium tracking-[0.16em] text-muted-foreground uppercase">Your original</p>
            <p className="mt-2 text-sm leading-relaxed whitespace-pre-wrap">{body}</p>
          </div>
          <div className="rounded-xl border border-primary/40 bg-primary/5 p-3">
            <p className="text-[11px] font-medium tracking-[0.16em] text-primary uppercase">Grok-enhanced donor copy</p>
            <p className="mt-2 text-sm leading-relaxed whitespace-pre-wrap">{review.enhanced}</p>
            {review.findings.length ? (
              <ul className="mt-3 space-y-1 text-xs text-muted-foreground">
                {review.findings.map((f) => (
                  <li key={f}>• {f}</li>
                ))}
              </ul>
            ) : null}
            <p className="mt-2 text-xs text-muted-foreground">{review.notes}</p>
          </div>
          <div className="lg:col-span-2 flex flex-wrap gap-2">
            <Button type="button" size="sm" variant={!useAi ? "gold" : "outline"} onClick={() => setUseAi(false)}>
              Publish my original
            </Button>
            <Button type="button" size="sm" variant={useAi ? "gold" : "outline"} onClick={() => setUseAi(true)}>
              Publish Grok-enhanced
            </Button>
            <p className="self-center text-xs text-muted-foreground">
              {useAi
                ? "Coach will see you used the Grok-enhanced donor copy."
                : "Coach still has the Grok notes. Donors see your original."}
            </p>
          </div>
        </div>
      ) : null}

      <div className="mt-4 flex flex-wrap gap-2">
        {aiEnabled ? (
          <Button
            type="button"
            size="lg"
            variant="outline"
            className="deal-cta"
            disabled={busy !== null}
            onClick={() => void grok()}
          >
            <Sparkles className="size-4" />
            {busy === "grok" ? "Grok is reading…" : "Ask Grok to review"}
          </Button>
        ) : null}
        <Button type="button" size="lg" variant="gold" className="deal-cta" disabled={busy !== null} onClick={() => void submit()}>
          <Upload className="size-4" />
          {busy === "file"
            ? "Filing…"
            : useAi
              ? "File Grok-enhanced · move the ball"
              : "File original · move the ball"}
        </Button>
      </div>
    </div>
  );
}

function PacketReviewNote() {
  return (
    <p className="mt-3 rounded-lg bg-primary/8 px-3 py-2 text-sm text-navy">
      Packet review is a studio tool. Students file the original. Review checks numbers and claims — it does not invent
      figures. Coaches see both copies. Donors only see the published packet. They never see the word Grok and they never
      see the student draft unless you publish it.
    </p>
  );
}

function QuestionRow({
  q,
  canAnswer,
  slug,
  onDone,
}: {
  q: DealQuestion;
  canAnswer: boolean;
  slug: string;
  onDone: () => Promise<void>;
}) {
  const [answer, setAnswer] = useState("");
  const [busy, setBusy] = useState(false);

  async function send() {
    if (answer.trim().length < 8) return;
    setBusy(true);
    try {
      const res = await answerDealQuestion({ data: { questionId: q.id, answer: answer.trim(), slug, ...identity() } });
      pingStadiumLive();
      toast.success(`Answer posted · ${res.points} yards.`);
      setAnswer("");
      await onDone();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not post the answer.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <li className="rounded-lg bg-muted/60 p-3">
      <p className="text-sm">{q.body}</p>
      <p className="mt-1 text-xs text-muted-foreground">
        {q.from_name} · {q.from_role} · {formatDateTime(q.created_at)}
      </p>
      {q.answer ? (
        <p className="mt-2 border-l-2 border-primary pl-3 text-sm">
          {q.answer}
          <span className="mt-1 block text-xs text-muted-foreground">
            {q.answered_by} · {q.answered_at ? formatDateTime(q.answered_at) : ""}
          </span>
        </p>
      ) : canAnswer ? (
        <div className="mt-2 flex flex-col gap-2">
          <Textarea value={answer} onChange={(e) => setAnswer(e.target.value)} placeholder="Answer for the donor." />
          <Button size="sm" variant="gold" disabled={busy} onClick={() => void send()}>
            Answer · 4 yards
          </Button>
        </div>
      ) : (
        <p className="mt-2 text-xs text-muted-foreground">Waiting on the studio.</p>
      )}
    </li>
  );
}

function AskForm({
  slug,
  email,
  name,
  role,
  signedIn,
  busy,
  setBusy,
  onDone,
}: {
  slug: string;
  email: string;
  name: string;
  role: string;
  signedIn: boolean;
  busy: boolean;
  setBusy: (v: boolean) => void;
  onDone: () => Promise<void>;
}) {
  const [body, setBody] = useState("");
  async function send() {
    setBusy(true);
    try {
      await postDealQuestion({ data: { slug, email, name, role, signedIn, body } });
      pingStadiumLive();
      toast.success("Question sent to the studio.");
      setBody("");
      await onDone();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not post the question.");
    } finally {
      setBusy(false);
    }
  }
  return (
    <div className="mt-4 border-t border-border pt-4">
      <Textarea value={body} onChange={(e) => setBody(e.target.value)} placeholder="Ask the studio a question." />
      <Button className="deal-cta mt-2" variant="outline" size="lg" disabled={busy} onClick={() => void send()}>
        Ask the studio
      </Button>
    </div>
  );
}
