import { Link, createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { PageHeader } from "@/components/archive-ui";
import { useI18n } from "@/components/shell";
import { phraseFromArchive } from "@/lib/archive/ask.functions";
import { composeAnswer } from "@/lib/archive/answer";
import { personById } from "@/lib/archive/catalog";
import { EVIDENCE_LABEL, TIER_LABEL } from "@/lib/archive/labels";
import { useLiveLibrary } from "@/lib/archive/live";
import { normalize } from "@/lib/archive/search";
import { useArchiveStore } from "@/lib/archive/store";

export const Route = createFileRoute("/research")({
  validateSearch: (search: Record<string, unknown>) =>
    ({
      q: typeof search.q === "string" && search.q ? search.q.slice(0, 500) : undefined,
    }) as { q?: string },
  component: ResearchPage,
});

const PROMPTS = [
  "When was Shaykh Ibrahim Niasse born?",
  "When did Shaykh Ibrahim first visit Kano?",
  "What is Kashif al-Ilbas?",
  "Quote Shaykh Ibrahim on the Fayda",
  "Who was Sayyid Ali Cisse?",
  "When was Medina Baye founded?",
];

function ResearchPage() {
  const { q = "" } = Route.useSearch();
  const { copy } = useI18n();
  const navigate = useNavigate();
  const lib = useLiveLibrary();
  const submissions = useArchiveStore((state) => state.submissions);
  const hydrated = useArchiveStore((state) => state.hydrated);
  const [draft, setDraft] = useState(q);
  const [phrasing, setPhrasing] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const [routeUsed, setRouteUsed] = useState<string | null>(null);

  useEffect(() => {
    setDraft(q);
    setPhrasing(null);
    setNotice(null);
    setError(null);
    setRouteUsed(null);
  }, [q]);

  const answer = q.trim() ? composeAnswer(q, lib) : null;
  const needle = normalize(q);
  const pending = hydrated
    ? submissions.filter((item) => {
        if (item.status === "approved" || item.status === "rejected") return false;
        const hay = normalize(`${item.title} ${item.description}`);
        return needle.length > 3 && hay.includes(needle.slice(0, 48));
      })
    : [];

  const lead =
    answer?.lead === "insufficient"
      ? copy.insufficient
      : answer?.lead === "quotation_refused"
        ? copy.quoteRefused
        : answer?.lead === "disagreement"
          ? copy.disagreement
          : copy.recordsLead;

  async function phrase() {
    if (!q.trim() || busy) return;
    setBusy(true);
    setError(null);
    setNotice(null);
    setPhrasing(null);
    try {
      const notes = submissions
        .filter((item) => item.status === "approved")
        .map((item) => ({ title: item.title, text: item.description, contributor: item.contributor }));
      const result = await Promise.race([
        phraseFromArchive({ data: { question: q, notes } }),
        new Promise<never>((_, reject) => {
          setTimeout(() => reject(new Error("Phrasing took too long. The records are the answer.")), 22_000);
        }),
      ]);
      if (!result.ok) {
        setError(result.error);
        return;
      }
      setRouteUsed(result.route);
      if (result.calledModel) setPhrasing(result.phrasing);
      else setNotice(result.notice);
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : "Phrasing failed.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div>
      <PageHeader
        kicker="Research desk"
        title="Ask only what the shelf can carry"
        lede="The answer is the records. A model, when it is used, may only rephrase them. Conversation on this page is not saved as fact."
      />
      <form
        className="flex flex-col gap-3 border-y border-ink/15 py-3 sm:flex-row"
        onSubmit={(event) => {
          event.preventDefault();
          void navigate({ to: "/research", search: { q: draft.trim() } });
        }}
      >
        <label className="sr-only" htmlFor="research-q">Question</label>
        <input id="research-q" value={draft} onChange={(event) => setDraft(event.target.value)} placeholder={copy.askPlaceholder} className="min-h-11 w-full bg-transparent text-lg outline-none" />
        <button type="submit" className="min-h-11 bg-brass px-4 text-sm text-paper">{copy.ask}</button>
      </form>

      {!q ? (
        <ul className="mt-6 divide-y divide-ink/10 border-y border-ink/10">
          {PROMPTS.map((prompt) => (
            <li key={prompt}>
              <button type="button" className="min-h-11 w-full py-2 text-left text-lg hover:text-brass" onClick={() => void navigate({ to: "/research", search: { q: prompt } })}>
                {prompt}
              </button>
            </li>
          ))}
        </ul>
      ) : null}

      {answer ? (
        <div className="mt-8">
          <p className="max-w-3xl text-2xl leading-snug">{lead}</p>

          {answer.disagreements.map((group) => (
            <div key={group.group} className="mt-6 border border-ink/15 bg-paper p-4">
              <p className="text-xs tracking-[0.16em] text-brass uppercase">Two accounts</p>
              <ul className="mt-3 space-y-3">
                {group.claims.map((claim) => (
                  <li key={claim.chunkId}>
                    <Link to="/works/$workId" params={{ workId: claim.workId }} className="underline decoration-brass underline-offset-4">
                      {claim.title}
                    </Link>
                    <span> reports {claim.claim}.</span>
                  </li>
                ))}
              </ul>
            </div>
          ))}

          {answer.citations.length ? (
            <ol className="mt-8 space-y-8">
              {answer.citations.map((citation, index) => (
                <li key={citation.chunkId}>
                  <p className="text-lg leading-relaxed">{citation.text}</p>
                  <div className="mt-3 text-sm text-muted">
                    <p>
                      <span className="text-brass tabular-nums">{index + 1}. </span>
                      <Link to="/works/$workId" params={{ workId: citation.workId }} className="text-ink underline decoration-brass underline-offset-4">
                        {citation.title}
                      </Link>
                    </p>
                    <p>Author: {citation.authorIds.length ? citation.authorIds.map((id) => personById(id)?.name ?? id).join(", ") : "Catalog, not an authorial work"}</p>
                    <p>Locator: {citation.page ? `Page ${citation.page}` : citation.timestamp ? citation.timestamp : citation.locator}</p>
                    <p>
                      {EVIDENCE_LABEL[citation.evidenceKind]} · Record tier {citation.recordTier} ({TIER_LABEL[citation.recordTier]}) · Underlying tier {citation.subjectTier}
                    </p>
                    {citation.isQuotation ? null : <p>Not a quotation from the underlying work.</p>}
                  </div>
                </li>
              ))}
            </ol>
          ) : null}

          {answer.relatedUncited.length ? (
            <section className="mt-10">
              <h2 className="text-xs tracking-[0.16em] text-brass uppercase">Not used as evidence</h2>
              <ul className="mt-3 divide-y divide-ink/10 border-y border-ink/10">
                {answer.relatedUncited.map((item) => (
                  <li key={item.workId} className="py-3 text-sm">
                    <Link to="/works/$workId" params={{ workId: item.workId }} className="underline decoration-brass underline-offset-4">
                      {item.title}
                    </Link>
                    <span className="block text-muted">{item.reason}</span>
                  </li>
                ))}
              </ul>
            </section>
          ) : null}

          {pending.length ? (
            <p className="mt-6 max-w-2xl text-sm">
              {copy.pending}{" "}
              <Link to="/curator" className="underline decoration-brass underline-offset-4">
                Open the review queue
              </Link>
            </p>
          ) : null}

          {!answer.enough ? (
            <p className="mt-6">
              <Link to="/submit" className="inline-flex min-h-11 items-center underline decoration-brass underline-offset-4">
                {copy.submitCta}
              </Link>
            </p>
          ) : (
            <div className="mt-8">
              <button type="button" onClick={() => void phrase()} disabled={busy} className="min-h-11 border border-ink/20 px-4 text-sm disabled:opacity-50">
                {busy ? "Phrasing…" : copy.phrase}
              </button>
              {routeUsed ? <p className="mt-2 text-xs tracking-widest text-muted uppercase">Route: {routeUsed}</p> : null}
              {notice ? <p className="mt-3 max-w-2xl text-sm text-muted">{notice}</p> : null}
              {error ? <p className="mt-3 max-w-2xl text-sm">{error}</p> : null}
              {phrasing ? (
                <aside className="mt-4 max-w-3xl border border-ink/15 bg-paper p-4">
                  <p className="text-xs tracking-[0.16em] text-brass uppercase">{copy.phrasing}</p>
                  <p className="mt-3 whitespace-pre-wrap leading-relaxed">{phrasing}</p>
                  <p className="mt-3 text-sm text-muted">{copy.check}</p>
                </aside>
              ) : null}
            </div>
          )}
        </div>
      ) : null}
    </div>
  );
}
