/**
 * DocBureauPanel — surfaces Investigation Bureau artefacts that touch a
 * specific doc_id on the /d/[docId] page.
 *
 * Server component. Resolves:
 *   - Evidence whose source_page_id starts with doc_id/p (FK via the
 *     chunks table would be cleaner but the LIKE prefix is fine and
 *     index-friendly).
 *   - Hypotheses whose evidence_refs contain any E-NNNN from this doc.
 *   - Contradictions whose chunks array contains an item with this doc_id.
 *   - Outliers (gaps) whose scope.doc_id == this doc_id.
 *   - Case reports whose body markdown references the doc_id.
 *
 * Renders nothing if all five lists are empty (doc untouched by bureau).
 */
import Link from "next/link";
import { pgQuery } from "@/lib/retrieval/db";

interface EvRow { evidence_id: string; grade: string; confidence_band: string | null; source_page_id: string }
interface HypRow { hypothesis_id: string; position: string; position_pt_br: string | null; confidence_band: string | null; posterior: number | string | null }
interface CtrRow { contradiction_id: string; topic: string; topic_pt_br: string | null; resolution_status: string }
interface GapRow { gap_id: string; description: string; description_pt_br: string | null; scope: unknown; status: string }
interface ReportRow { slug: string; topic: string }

const BAND_TONE: Record<string, string> = {
  high: "text-[#06d6a0]", medium: "text-[#3fde6a]",
  low: "text-[#ffa500]", speculation: "text-[#ff6ec7]",
};

const GRADE_TONE: Record<string, string> = {
  A: "text-[#06d6a0] border-[#06d6a0]",
  B: "text-[#3fde6a] border-[#3fde6a]",
  C: "text-[#ffa500] border-[#ffa500]",
};

export async function DocBureauPanel({ docId }: { docId: string }) {
  // Evidence on this doc (cheap).
  const ev: EvRow[] = await pgQuery<EvRow>(
    `SELECT evidence_id, grade, confidence_band, source_page_id
       FROM public.evidence
      WHERE source_page_id LIKE $1 || '/%'
      ORDER BY evidence_id LIMIT 20`,
    [docId],
  ).catch(() => []);

  // Hypotheses citing any of the evidence_ids above.
  const evIds = ev.map((e) => e.evidence_id);
  const hyp: HypRow[] = evIds.length > 0
    ? await pgQuery<HypRow>(
        `SELECT hypothesis_id, position, position_pt_br, confidence_band, posterior
           FROM public.hypotheses
          WHERE EXISTS (
            SELECT 1 FROM jsonb_array_elements(evidence_refs) er
            WHERE er->>'evidence_id' = ANY($1::text[])
          )
          ORDER BY hypothesis_id LIMIT 12`,
        [evIds],
      ).catch(() => [])
    : [];

  // Contradictions whose chunks[] has any chunk with this doc_id.
  const ctr: CtrRow[] = await pgQuery<CtrRow>(
    `SELECT contradiction_id, topic, topic_pt_br, resolution_status
       FROM public.contradictions
      WHERE EXISTS (
        SELECT 1 FROM jsonb_array_elements(chunks) c
        WHERE c->>'doc_id' = $1
      )
      ORDER BY contradiction_id LIMIT 8`,
    [docId],
  ).catch(() => []);

  // Outliers (gaps with scope.doc_id matching).
  const gap: GapRow[] = await pgQuery<GapRow>(
    `SELECT gap_id, description, description_pt_br, scope, status
       FROM public.gaps
      WHERE scope->>'doc_id' = $1
      ORDER BY gap_id LIMIT 8`,
    [docId],
  ).catch(() => []);

  // Case reports referencing this doc_id in the body. We don't store body
  // in pg; instead we scan the reports/ dir filesystem-side for now.
  // (Lightweight — bureau reports are O(10) files.)
  let reports: ReportRow[] = [];
  try {
    const { readdir, readFile } = await import("node:fs/promises");
    const path = await import("node:path");
    const dir = path.join(process.env.CASE_ROOT || "/data/ufo/case", "reports");
    const files = await readdir(dir).catch(() => [] as string[]);
    const found: ReportRow[] = [];
    for (const f of files.filter((x) => x.endsWith(".md"))) {
      const md = await readFile(path.join(dir, f), "utf-8");
      if (md.includes(docId)) {
        const topicMatch = md.match(/topic:\s*"([^"]+)"/);
        found.push({ slug: f.replace(/\.md$/, ""), topic: topicMatch?.[1] ?? f });
      }
    }
    reports = found;
  } catch { /* fine */ }

  const total = ev.length + hyp.length + ctr.length + gap.length + reports.length;
  if (total === 0) {
    return (
      <section className="mb-6 rounded-lg border border-dashed border-[rgba(127,219,255,0.18)] bg-[#0d1220] p-4">
        <div className="flex items-baseline justify-between flex-wrap gap-2">
          <div className="text-[10px] font-mono text-[#5a6678] uppercase tracking-wider">
            // Investigation Bureau — untouched
          </div>
          <Link
            href={`/?launch=${encodeURIComponent(docId)}`}
            className="text-[10px] font-mono text-[#e0c080] hover:underline"
          >
            launch an investigation →
          </Link>
        </div>
        <p className="text-[11px] text-[#5a6678] font-mono mt-2">
          No detective has produced an artefact for this document yet.
        </p>
      </section>
    );
  }

  return (
    <section className="mb-6 rounded-lg border border-[rgba(224,192,128,0.18)] bg-gradient-to-br from-[rgba(224,192,128,0.04)] to-transparent p-4">
      <div className="flex items-baseline justify-between flex-wrap gap-2 mb-3">
        <div className="text-[10px] font-mono text-[#e0c080] uppercase tracking-wider">
          // Investigation Bureau · {total} artefact{total === 1 ? "" : "s"} touch this doc
        </div>
        <Link href="/bureau" className="text-[10px] font-mono text-[#e0c080] hover:underline">
          full bureau →
        </Link>
      </div>

      <div className="grid md:grid-cols-2 gap-3">
        {hyp.length > 0 && (
          <Panel title="Hypotheses" color="text-[#7fdbff]" border="border-[rgba(127,219,255,0.18)]">
            {hyp.map((h) => {
              const tone = (h.confidence_band && BAND_TONE[h.confidence_band]) || "text-[#9aa6b8]";
              const post = h.posterior !== null ? Number(h.posterior) : null;
              return (
                <Link key={h.hypothesis_id} href={`/h/${h.hypothesis_id}`}
                  className="block py-1.5 border-t border-[rgba(127,219,255,0.08)] first:border-t-0 hover:bg-[rgba(127,219,255,0.04)]">
                  <div className="flex items-baseline justify-between gap-2">
                    <span className="text-[10px] font-mono text-[#5a6678]">{h.hypothesis_id}</span>
                    <span className={`text-[10px] font-mono ${tone}`}>
                      {h.confidence_band ?? "—"}{post !== null && ` · ${post.toFixed(2)}`}
                    </span>
                  </div>
                  <div className="text-[12px] text-[#cbd2dd] leading-snug mt-0.5">{h.position_pt_br || h.position}</div>
                </Link>
              );
            })}
          </Panel>
        )}

        {ev.length > 0 && (
          <Panel title="Evidence" color="text-[#06d6a0]" border="border-[rgba(6,214,160,0.18)]">
            {ev.map((e) => {
              const tone = (e.grade && GRADE_TONE[e.grade]) || "text-[#9aa6b8] border-[#9aa6b8]";
              return (
                <div key={e.evidence_id} className="py-1.5 border-t border-[rgba(6,214,160,0.08)] first:border-t-0">
                  <div className="flex items-baseline justify-between gap-2">
                    <span className="text-[10px] font-mono text-[#5a6678]">{e.evidence_id}</span>
                    <span className={`px-1.5 py-0.5 rounded text-[10px] font-mono uppercase border ${tone}`}>
                      Grade {e.grade}
                    </span>
                  </div>
                  <div className="text-[11px] font-mono text-[#5a6678] mt-0.5">{e.source_page_id}</div>
                </div>
              );
            })}
          </Panel>
        )}

        {ctr.length > 0 && (
          <Panel title="Contradictions" color="text-[#ff8a4d]" border="border-[rgba(255,138,77,0.18)]">
            {ctr.map((c) => (
              <div key={c.contradiction_id} className="py-1.5 border-t border-[rgba(255,138,77,0.08)] first:border-t-0">
                <div className="flex items-baseline justify-between gap-2">
                  <span className="text-[10px] font-mono text-[#5a6678]">{c.contradiction_id}</span>
                  <span className="text-[10px] font-mono text-[#9aa6b8]">{c.resolution_status}</span>
                </div>
                <div className="text-[12px] text-[#cbd2dd] leading-snug mt-0.5">{c.topic_pt_br || c.topic}</div>
              </div>
            ))}
          </Panel>
        )}

        {gap.length > 0 && (
          <Panel title="Outliers" color="text-[#ffd23f]" border="border-[rgba(255,210,63,0.25)]">
            {gap.map((g) => {
              const s = (g.scope ?? {}) as Record<string, unknown>;
              const title = (s.title_pt_br as string) || (s.title as string)
                || g.description_pt_br || g.description;
              return (
                <div key={g.gap_id} className="py-1.5 border-t border-[rgba(255,210,63,0.08)] first:border-t-0">
                  <div className="flex items-baseline justify-between gap-2">
                    <span className="text-[10px] font-mono text-[#5a6678]">{g.gap_id}</span>
                    <span className="text-[10px] font-mono text-[#9aa6b8]">{g.status}</span>
                  </div>
                  <div className="text-[12px] text-[#cbd2dd] leading-snug mt-0.5">{title}</div>
                </div>
              );
            })}
          </Panel>
        )}

        {reports.length > 0 && (
          <Panel title="Case reports referencing this doc" color="text-[#e0c080]" border="border-[rgba(224,192,128,0.25)]">
            {reports.map((r) => (
              <Link key={r.slug} href={`/c/${r.slug}`}
                className="block py-1.5 border-t border-[rgba(224,192,128,0.08)] first:border-t-0 hover:bg-[rgba(224,192,128,0.04)]">
                <div className="text-[10px] font-mono text-[#5a6678]">/c/{r.slug}</div>
                <div className="text-[12px] text-[#e0c080] leading-snug mt-0.5 font-medium">{r.topic}</div>
              </Link>
            ))}
          </Panel>
        )}
      </div>
    </section>
  );
}

function Panel({ title, color, border, children }: {
  title: string; color: string; border: string; children: React.ReactNode;
}) {
  return (
    <div className={`rounded border ${border} bg-[#0d1220] p-3`}>
      <div className={`text-[10px] font-mono uppercase tracking-wider ${color} mb-1`}>{title}</div>
      <div>{children}</div>
    </div>
  );
}
