// Single sidebar for the pivoted shell. Lists every section grouped under
// Structure / Findings. Each row shows: title, count, last-run timestamp,
// per-section [Analyze] button, and is itself clickable to toggle the matching
// pane open in the main workspace.

"use client";

import { useOpenPanes, SECTION_TITLES, type SectionPaneId } from "../../lib/workspace/openPanesStore";
import { useAnalysis } from "../../lib/workspace/analysisStore";
import { Spinner } from "./Spinner";
import { useState } from "react";

const STRUCTURE: SectionPaneId[] = ["concepts", "model", "requirements"];
const FINDINGS: SectionPaneId[] = ["assumptions", "risks", "inconsistencies"];

export function LeftSidebar() {
  const [collapsed, setCollapsed] = useState(false);

  if (collapsed) {
    return (
      <aside className="leftsidebar leftsidebar-collapsed" aria-label="Sections">
        <button className="leftsidebar-collapse-toggle" type="button" onClick={() => setCollapsed(false)} aria-label="Expand sidebar">
          ›
        </button>
      </aside>
    );
  }

  return (
    <aside className="leftsidebar" aria-label="Sections">
      <div className="leftsidebar-head">
        <span className="leftsidebar-title">Workspace</span>
        <button className="leftsidebar-collapse-toggle" type="button" onClick={() => setCollapsed(true)} aria-label="Collapse sidebar">
          ‹
        </button>
      </div>
      <Group label="Structure" sections={STRUCTURE} />
      <Group label="Findings" sections={FINDINGS} />
    </aside>
  );
}

function Group({ label, sections }: { label: string; sections: SectionPaneId[] }) {
  return (
    <div className="leftsidebar-group">
      <div className="leftsidebar-group-label">{label}</div>
      <ul className="leftsidebar-list">
        {sections.map(s => (
          <SectionRow key={s} id={s} />
        ))}
      </ul>
    </div>
  );
}

function SectionRow({ id }: { id: SectionPaneId }) {
  const { isSectionOpen, toggleSection } = useOpenPanes();
  const { terms, requirements, findings, inFlight, runs, analyze } = useAnalysis();

  const open = isSectionOpen(id);
  const count = sectionCount(id, { terms, requirements, findings });
  const pending = pendingCount(id, { terms, requirements, findings });
  // Spinner is on whenever:
  //  - the user just clicked Analyze on this section (inFlight)
  //  - the user clicked Analyze All
  //  - the server has a "running" AnalysisRun for this section (catches
  //    background runs like seed-finalize and the first-paint auto-analyze
  //    that the local inFlight set doesn't know about). The analysisStore
  //    polls `runs` every 3s while anything is running, so this stays
  //    truthy until the run actually finishes.
  const running =
    inFlight.has(id) ||
    inFlight.has("all") ||
    (id === "concepts" && (inFlight.has("taxonomy") || inFlight.has("glossary"))) ||
    runs[id]?.status === "running" ||
    runs.all?.status === "running" ||
    (id === "concepts" &&
      (runs.taxonomy?.status === "running" || runs.glossary?.status === "running"));

  // ONE number per row: pending if there's review work, otherwise total.
  // Runs the user the most useful signal first ("how much attention does
  // this section need?") and avoids the duplicate-count effect when
  // pending === total because nothing is accepted yet.
  const showPending = pending > 0;

  return (
    <li className={`leftsidebar-row ${open ? "leftsidebar-row-open" : ""}`}>
      <button
        type="button"
        className="leftsidebar-row-main"
        onClick={() => toggleSection(id)}
        aria-expanded={open}
        aria-label={
          showPending
            ? `${SECTION_TITLES[id]} — ${pending} pending review`
            : `${SECTION_TITLES[id]} (${count})`
        }
      >
        <span className="leftsidebar-row-title">{SECTION_TITLES[id]}</span>
        {showPending ? (
          <span className="leftsidebar-pending-chip" title="Pending review">
            {pending}
          </span>
        ) : (
          <span className="leftsidebar-row-count">{count}</span>
        )}
      </button>
      <button
        type="button"
        className={`leftsidebar-analyze ${running ? "leftsidebar-analyze-running" : ""}`}
        title={running ? "Analyzing…" : `Re-run ${SECTION_TITLES[id]} analysis`}
        onClick={e => {
          e.stopPropagation();
          void analyze(id);
        }}
        disabled={running}
        aria-label={running ? "Analyzing" : `Re-run ${SECTION_TITLES[id]} analysis`}
      >
        {running ? <Spinner /> : <span aria-hidden="true">↻</span>}
      </button>
    </li>
  );
}

function sectionCount(
  id: SectionPaneId,
  data: {
    terms: { id: string; status: string }[];
    requirements: { id: string; status: string }[];
    findings: { kind: string; status: string }[];
  }
): number {
  if (id === "concepts") return data.terms.length;
  if (id === "model") return 0; // Model count is shown inside the pane itself.
  if (id === "requirements") return data.requirements.length;
  return data.findings.filter(f => f.kind === idToFindingKind(id)).length;
}

/** Count items the user hasn't reviewed yet (suggested + deprecated). The
 *  most useful navigation cue we can put in the sidebar — tells the user
 *  where attention is needed at a glance. */
function pendingCount(
  id: SectionPaneId,
  data: {
    terms: { status: string }[];
    requirements: { status: string }[];
    findings: { kind: string; status: string }[];
  }
): number {
  const isPending = (s: string) => s === "suggested" || s === "deprecated";
  if (id === "concepts") return data.terms.filter(t => isPending(t.status)).length;
  if (id === "requirements") return data.requirements.filter(r => isPending(r.status)).length;
  if (id === "model") return 0; // Model pending count needs ModelStore — surfaced in the pane header.
  return data.findings.filter(f => f.kind === idToFindingKind(id) && isPending(f.status)).length;
}

function idToFindingKind(id: SectionPaneId): string {
  if (id === "assumptions") return "assumption";
  if (id === "risks") return "risk";
  if (id === "inconsistencies") return "inconsistency";
  return "";
}

