// Project Intelligence operator surface. All data comes through the authenticated
// same-origin BFF; no Project Intelligence or provider credential enters the browser.
const PI_TABS = [
  { id: "ask", label: "Ask" },
  { id: "architecture", label: "Architecture" },
  { id: "freshness", label: "Freshness" },
  { id: "drift", label: "Drift" },
];

function piWhen(value) {
  if (!value) return "—";
  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString();
}

function piShortSha(value) { return value ? String(value).slice(0, 8) : "—"; }
function piTone(status) {
  if (["ready", "fresh", "current"].includes(status)) return "ok";
  if (["degraded", "advanced", "stale", "incomplete", "syncing-or-degraded"].includes(status)) return "warn";
  return "bad";
}

function PIStatus({ status, label }) {
  return <span className={cls("badge", piTone(status))}><span className="d" />{label || status || "unknown"}</span>;
}

function PIEmpty({ icon = "search", title, children }) {
  return <div className="pi-empty"><Icon name={icon} size={22} /><b>{title}</b><p>{children}</p></div>;
}

function PIEvidenceCard({ item, cited, onInspect }) {
  const reference = item.repository ? `${item.repository}@${piShortSha(item.commitSha)}` : `${item.sourceId}@${item.snapshotId}`;
  return (
    <article className={cls("pi-evidence", cited && "cited")}>
      <div className="pi-evidence-top">
        <span className="pi-evidence-kind"><Icon name={item.repository ? "git" : "activity"} size={14} />{item.type}</span>
        <PIStatus status={item.fresh ? "fresh" : "stale"} />
      </div>
      <h3>{item.title || "Untitled evidence"}</h3>
      <code>{reference}</code>
      {item.path && <p className="pi-path">{item.path}{item.line ? `:${item.line}` : ""}</p>}
      {item.recordRef && <p className="pi-path">{item.recordRef}</p>}
      <p className="pi-excerpt">{item.excerpt || "No excerpt was returned."}</p>
      <div className="pi-evidence-foot">
        <span>{item.capturedAt ? `Captured ${piWhen(item.capturedAt)}` : item.generation ? `Generation ${item.generation}` : "Exact provenance available"}</span>
        <div className="flex" style={{ gap: 6 }}>
          <button className="btn btn-subtle btn-sm" onClick={() => onInspect(item)}>Inspect</button>
          {item.url && <a className="btn btn-ghost btn-sm" href={item.url} target="_blank" rel="noopener noreferrer"><Icon name="external" size={13} />Open</a>}
        </div>
      </div>
    </article>
  );
}

function PIProvenanceDrawer({ item, onClose }) {
  const closeRef = useRef(null);
  useEffect(() => { closeRef.current?.focus(); const key = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", key); return () => window.removeEventListener("keydown", key); }, [onClose]);
  if (!item) return null;
  const rows = Object.entries(item).filter(([key, value]) => value != null && key !== "excerpt" && key !== "url");
  return <div className="drawer-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
    <aside className="drawer" role="dialog" aria-modal="true" aria-labelledby="pi-provenance-title">
      <div className="drawer-head"><div><span className="eyebrow">Provenance</span><h2 id="pi-provenance-title" style={{ marginTop: 6 }}>{item.title || item.name || item.id}</h2></div><button ref={closeRef} className="icon-btn" onClick={onClose} aria-label="Close provenance"><Icon name="x" /></button></div>
      <div className="drawer-body">
        <div className="pi-provenance-grid">{rows.map(([key, value]) => <React.Fragment key={key}><b>{key}</b><code>{typeof value === "object" ? JSON.stringify(value, null, 2) : String(value)}</code></React.Fragment>)}</div>
        {item.excerpt && <div className="field"><label>Bounded excerpt</label><pre className="logbox" style={{ whiteSpace: "pre-wrap" }}>{item.excerpt}</pre></div>}
        {item.url && <a className="btn btn-ghost" href={item.url} target="_blank" rel="noopener noreferrer"><Icon name="external" size={14} />Open safe source link</a>}
      </div>
    </aside>
  </div>;
}

function PITaskDialog({ answer, repositories, onClose, toast }) {
  const available = [...new Set((answer.evidence || []).map((item) => item.repository).filter(Boolean))];
  const [repository, setRepository] = useState(available.length === 1 ? available[0] : "");
  const [title, setTitle] = useState(`Follow up: ${answer.question}`.slice(0, 140));
  const [outcome, setOutcome] = useState("");
  const [busy, setBusy] = useState(false);
  const modalRef = useRef(null);
  useEffect(() => {
    modalRef.current?.querySelector("input,select,textarea,button")?.focus();
    const key = (event) => {
      if (event.key === "Escape" && !busy) onClose();
      if (event.key === "Tab" && modalRef.current) {
        const focusable = [...modalRef.current.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href]')];
        if (!focusable.length) return;
        const first = focusable[0], last = focusable[focusable.length - 1];
        if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
        else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
      }
    };
    window.addEventListener("keydown", key); return () => window.removeEventListener("keydown", key);
  }, [busy, onClose]);
  const create = async () => {
    if (!repository || !title.trim() || busy) return;
    setBusy(true);
    const manifest = (answer.evidence || []).map((item) => item.repository
      ? `- repository=${item.repository}; commit=${item.commitSha}; generation=${item.generation || "unknown"}; path=${item.path || "n/a"}`
      : `- source=${item.sourceId}; snapshot=${item.snapshotId}; checksum=${item.checksum}; record=${item.recordRef || "n/a"}`
    ).join("\n");
    const description = [
      "Project Intelligence handoff", "", `Original question: ${answer.question}`, "", "Grounded answer:", answer.answer,
      "", `Desired outcome: ${outcome.trim() || "Investigate the cited finding and implement the appropriate verified change."}`,
      "", `Execution repository: ${repository}`, "", "Provenance manifest:", manifest,
      "", `Query ID: ${answer.queryId}`, `Generated at: ${answer.generatedAt}`,
      "", "Important: re-run Project Intelligence ensure-fresh at execution time. Re-plan if the base branch or a required source has advanced.",
    ].join("\n");
    try {
      await HERMES.createTask({ title: title.trim(), description, column: "triage", tags: [repository, "project-intelligence"], idempotency_key: `pi:${answer.queryId}:${repository}` });
      toast("Project Intelligence task created in Triage"); onClose();
    } catch (error) { toast(error.message || "Task creation failed"); setBusy(false); }
  };
  return <div className="modal-scrim" onMouseDown={(e) => e.target === e.currentTarget && !busy && onClose()}>
    <div ref={modalRef} className="modal" role="dialog" aria-modal="true" aria-labelledby="pi-task-title">
      <div className="modal-head"><div className="ic"><Icon name="kanban" /></div><div><h2 id="pi-task-title">Review Sylar task</h2><p>Nothing executes automatically. Sylar will revalidate the exact knowledge when work starts.</p></div><button className="btn btn-subtle btn-sm x" onClick={onClose} disabled={busy} aria-label="Close"><Icon name="x" /></button></div>
      <div className="modal-body">
        {answer.freshness?.status !== "fresh" && <div className="pi-alert warn" role="alert"><Icon name="activity" size={16} /><div><b>Knowledge is {answer.freshness?.status}</b><p>Review the warning and expect Sylar to re-plan against current evidence at execution.</p></div></div>}
        <div className="field"><label htmlFor="pi-task-title-input">Title</label><input id="pi-task-title-input" className="input" value={title} maxLength="160" onChange={(e) => setTitle(e.target.value)} /></div>
        <div className="field"><label htmlFor="pi-task-repository">Execution repository</label><select id="pi-task-repository" className="select" value={repository} onChange={(e) => setRepository(e.target.value)}><option value="">Choose a repository…</option>{(available.length ? available : repositories.map((item) => item.repo)).map((repo) => <option key={repo}>{repo}</option>)}</select>{available.length > 1 && <small className="faint">This answer spans multiple repositories. Choose the one Sylar may change.</small>}</div>
        <div className="field"><label htmlFor="pi-task-outcome">Desired outcome</label><textarea id="pi-task-outcome" className="pi-textarea small" value={outcome} onChange={(e) => setOutcome(e.target.value)} placeholder="What should Sylar verify or change?" /></div>
        <div className="pi-task-preview"><b>Evidence attached by stable identifier</b><span>{answer.evidence.length} items · {new Set(answer.evidence.map((item) => item.repository || item.sourceId)).size} sources</span></div>
      </div>
      <div className="modal-foot"><button className="btn btn-ghost" onClick={onClose} disabled={busy}>Cancel</button><button className="btn btn-primary" disabled={!repository || !title.trim() || busy} onClick={create}>{busy ? "Creating…" : "Create in Triage"}</button></div>
    </div>
  </div>;
}

function PIAsk({ overview, toast, onInspect }) {
  const [question, setQuestion] = useState("");
  const [project, setProject] = useState("");
  const [repository, setRepository] = useState("");
  const [source, setSource] = useState("");
  const [environment, setEnvironment] = useState("");
  const [synthesize, setSynthesize] = useState(true);
  const [busy, setBusy] = useState(false);
  const [result, setResult] = useState(null);
  const [error, setError] = useState("");
  const [taskOpen, setTaskOpen] = useState(false);
  const abortRef = useRef(null);
  const taskButtonRef = useRef(null);
  useEffect(() => () => abortRef.current?.abort(), []);
  const examples = ["Where is ArogyaLens deployed?", "Which services depend on the provider gateway?", "What documentation needs review after recent code changes?"];
  const ask = async (event) => {
    event?.preventDefault();
    if (question.trim().length < 2) return;
    abortRef.current?.abort(); const ctrl = new AbortController(); abortRef.current = ctrl;
    setBusy(true); setError("");
    try {
      const response = await HERMES.intelligenceQuery({ question, filters: { projects: project ? [project] : [], repositories: repository ? [repository] : [], sources: source ? [source] : [], environments: environment ? [environment] : [] }, limit: 30, synthesize }, { signal: ctrl.signal });
      setResult(response);
    } catch (err) { if (err.name !== "AbortError") setError(err.message || "Project Intelligence query failed"); }
    finally { if (abortRef.current === ctrl) setBusy(false); }
  };
  const cited = new Set((result?.citations || []).map((item) => item.id));
  const closeTask = () => { setTaskOpen(false); requestAnimationFrame(() => taskButtonRef.current?.focus()); };
  const environments = [...new Set((overview?.sourceRows || []).map((item) => item.environment).filter((value) => value && value !== "all"))];
  const projects = [...new Map((overview?.repositoryRows || []).map((item) => [item.projectId, item.projectName || item.projectId]).filter(([id]) => id)).entries()];
  return <div className="pi-ask-layout">
    <form className="card pi-query-card" onSubmit={ask}>
      <div className="field"><label htmlFor="pi-question">Question</label><textarea id="pi-question" className="pi-textarea" maxLength="4000" value={question} onChange={(e) => setQuestion(e.target.value)} placeholder="Ask about architecture, deployments, dependencies, documentation, or operations…" /></div>
      <div className="pi-filter-grid">
        <div className="field"><label htmlFor="pi-project-filter">Project</label><select id="pi-project-filter" className="select" value={project} onChange={(e) => setProject(e.target.value)}><option value="">All projects</option>{projects.map(([id, name]) => <option key={id} value={id}>{name}</option>)}</select></div>
        <div className="field"><label htmlFor="pi-repo-filter">Repository</label><select id="pi-repo-filter" className="select" value={repository} onChange={(e) => setRepository(e.target.value)}><option value="">All authorized</option>{(overview?.repositoryRows || []).map((item) => <option key={item.repo}>{item.repo}</option>)}</select></div>
        <div className="field"><label htmlFor="pi-source-filter">Source</label><select id="pi-source-filter" className="select" value={source} onChange={(e) => setSource(e.target.value)}><option value="">All authorized</option>{(overview?.sourceRows || []).map((item) => <option key={item.sourceId}>{item.sourceId}</option>)}</select></div>
        <div className="field"><label htmlFor="pi-env-filter">Environment</label><select id="pi-env-filter" className="select" value={environment} onChange={(e) => setEnvironment(e.target.value)}><option value="">All environments</option>{environments.map((item) => <option key={item}>{item}</option>)}</select></div>
      </div>
      <div className="pi-query-actions"><label className="pi-toggle-label"><Toggle on={synthesize} onChange={setSynthesize} /><span><b>Summarize evidence</b><small>Falls back to ranked evidence if synthesis is unavailable.</small></span></label><button className="btn btn-primary" disabled={busy || question.trim().length < 2}>{busy ? <><span className="dotpulse" />Retrieving…</> : <><Icon name="sparkle" size={15} />Answer with current evidence</>}</button></div>
      <div className="pi-examples"><span>Try:</span>{examples.map((value) => <button type="button" key={value} onClick={() => setQuestion(value)}>{value}</button>)}</div>
    </form>
    <section aria-live="polite" aria-busy={busy}>
      {error && <div className="card pi-alert bad" role="alert"><Icon name="activity" /><div><b>Query unavailable</b><p>{error}</p></div></div>}
      {!result && !error && <PIEmpty title="Ask across every current project">Answers stay grounded in exact Git commits and independently versioned operational snapshots.</PIEmpty>}
      {result && <>
        <article className="card pi-answer">
          <div className="pi-answer-head"><div><span className="eyebrow">Grounded answer</span><h2>{result.question}</h2></div><div className="flex" style={{ gap: 7, flexWrap: "wrap" }}>{result.scope?.inferredProject && <span className="badge pri">Scoped to {result.scope.inferredProject.name}</span>}<PIStatus status={result.freshness?.status} /><span className="badge">{result.confidence} confidence</span></div></div>
          {result.freshness?.warnings?.length > 0 && <div className={cls("pi-alert", result.freshness.status === "advanced" ? "warn" : "bad")}><Icon name="activity" size={16} /><div><b>{result.freshness.status === "advanced" ? "Knowledge advanced" : "Evidence is degraded"}</b><p>{result.freshness.warnings.join(" · ")}</p></div></div>}
          <div className="pi-answer-copy">{result.answer}</div>
          {result.conflicts?.length > 0 && <div className="pi-conflicts"><b>Conflicting evidence</b>{result.conflicts.map((item, index) => <p key={index}>{item}</p>)}</div>}
          <div className="pi-answer-meta"><span>{result.evidence.length} evidence items</span><span>{result.synthesis?.completed ? `Synthesized with ${result.synthesis.model}` : `Retrieval-only · ${result.synthesis?.fallbackReason || "requested"}`}</span><span>{piWhen(result.generatedAt)}</span></div>
          <button ref={taskButtonRef} className="btn btn-primary" disabled={!result.evidence.length} onClick={() => setTaskOpen(true)}><Icon name="kanban" size={15} />Open as Sylar task</button>
        </article>
        <div className="pi-section-head"><div><h2>Evidence</h2><p>Every item retains its exact commit or snapshot identifier.</p></div></div>
        <div className="pi-evidence-grid">{result.evidence.map((item) => <PIEvidenceCard key={item.id} item={item} cited={cited.has(item.id)} onInspect={onInspect} />)}</div>
      </>}
    </section>
    {taskOpen && result && <PITaskDialog answer={result} repositories={overview?.repositoryRows || []} onClose={closeTask} toast={toast} />}
  </div>;
}

function PIArchitecture({ overview, onInspect }) {
  const [data, setData] = useState(null); const [error, setError] = useState("");
  const [project, setProject] = useState(""); const [environment, setEnvironment] = useState("");
  const [selectedNode, setSelectedNode] = useState(""); const [typeFilter, setTypeFilter] = useState("all");
  const load = useCallback(() => { setError(""); setData(null); HERMES.intelligenceArchitecture({ project, environment, nodeLimit: 250, edgeLimit: 500 }).then(setData).catch((e) => setError(e.message)); }, [project, environment]);
  useEffect(load, [load]);
  if (error) return <div className="card pi-alert bad"><Icon name="activity" /><div><b>Architecture unavailable</b><p>{error}</p></div><button className="btn btn-ghost btn-sm" onClick={load}>Retry</button></div>;
  if (!data) return <PIEmpty icon="activity" title="Loading architecture">Building the accessible graph and relationship table.</PIEmpty>;
  const allNodes = data.nodes || []; const allEdges = data.edges || [];
  const scopedIds = new Set(project ? allNodes.filter((node) => node.type === "project").map((node) => node.id) : allNodes.map((node) => node.id));
  if (project) for (let depth = 0; depth < 4; depth += 1) allEdges.forEach((edge) => { if (scopedIds.has(edge.from)) scopedIds.add(edge.to); if (scopedIds.has(edge.to)) scopedIds.add(edge.from); });
  const nodes = allNodes.filter((node) => scopedIds.has(node.id));
  const edges = allEdges.filter((edge) => scopedIds.has(edge.from) && scopedIds.has(edge.to));
  const nodeById = new Map(nodes.map((node) => [node.id, node]));
  const projects = [...new Map((overview?.repositoryRows || []).map((item) => [item.projectId, item.projectName || item.projectId]).filter(([id]) => id)).entries()];
  const environments = [...new Set((overview?.sourceRows || []).map((item) => item.environment).filter((value) => value && value !== "all"))];
  const typeGroup = (node) => {
    if (node.type === "project") return "product";
    if (["repository", "github-repository"].includes(node.type)) return "code";
    if (/document|book|map|template|knowledge/.test(node.type)) return "knowledge";
    if (/runtime|container|service|endpoint|deployment/.test(node.type)) return "runtime";
    if (/aws|azure|cloud|instance|static-ip|alarm/.test(node.type)) return "infrastructure";
    return "system";
  };
  const groups = [
    ["product", "Project"], ["code", "Code"], ["system", "Systems"],
    ["knowledge", "Knowledge"], ["runtime", "Runtime"], ["infrastructure", "Infrastructure"],
  ];
  const projectNodes = nodes.filter((node) => node.type === "project");
  const relatedIds = new Set();
  if (selectedNode) {
    relatedIds.add(selectedNode);
    edges.forEach((edge) => { if (edge.from === selectedNode) relatedIds.add(edge.to); if (edge.to === selectedNode) relatedIds.add(edge.from); });
  }
  const shownNodes = nodes.filter((node) => typeFilter === "all" || typeGroup(node) === typeFilter);
  const shownEdges = selectedNode ? edges.filter((edge) => edge.from === selectedNode || edge.to === selectedNode) : edges;
  const inspectNode = (node) => { setSelectedNode(node.id); onInspect(node); };
  return <div className="grid" style={{ gap: "var(--gap)" }}>
    <div className="card pi-architecture-filters"><div><b>Explore one system at a time</b><p>Start with a project, then inspect only its code, knowledge, runtime, and infrastructure relationships.</p></div><select className="select" aria-label="Architecture project" value={project} onChange={(e) => { setProject(e.target.value); setSelectedNode(""); }}><option value="">Portfolio overview</option>{projects.map(([id, name]) => <option key={id} value={id}>{name}</option>)}</select><select className="select" aria-label="Architecture environment" value={environment} onChange={(e) => { setEnvironment(e.target.value); setSelectedNode(""); }}><option value="">All environments</option>{environments.map((item) => <option key={item}>{item}</option>)}</select></div>
    {(data.nodes || []).length >= 250 && <div className="pi-alert warn"><Icon name="activity" /><div><b>Graph capped at 250 nodes</b><p>Narrow project or environment filters before expanding the portfolio.</p></div></div>}
    {!project && <div className="card"><div className="card-head"><div><h2>Systems portfolio</h2><p>Select a project to open its evidence-backed topology.</p></div><span className="badge">{projectNodes.length} projects</span></div><div className="pi-project-grid">{projectNodes.map((node) => { const count = edges.filter((edge) => edge.from === node.id || edge.to === node.id).length; return <button key={node.id} className="pi-project-card" onClick={() => setProject(node.attributes?.projectId || node.name)}><span className="pi-project-mark"><Icon name="activity" size={16} /></span><span><b>{node.name}</b><small>{count} direct relationships</small></span><Icon name="chevron" size={15} /></button>; })}</div></div>}
    {project && <div className="card pi-topology-card"><div className="card-head"><div><h2>{projects.find(([id]) => id === project)?.[1] || project} topology</h2><p>{nodes.length} nodes and {edges.length} relationships in the current evidence snapshot.</p></div>{selectedNode && <button className="btn btn-ghost btn-sm" onClick={() => setSelectedNode("")}>Show all</button>}</div>
      <div className="pi-type-filters" role="group" aria-label="Filter topology by layer"><button className={cls("pi-type-chip", typeFilter === "all" && "on")} onClick={() => setTypeFilter("all")}>All layers</button>{groups.map(([id, label]) => <button key={id} className={cls("pi-type-chip", typeFilter === id && "on")} onClick={() => setTypeFilter(id)}>{label}</button>)}</div>
      <div className="pi-topology" aria-label="Layered project topology">{groups.filter(([id]) => typeFilter === "all" || typeFilter === id).map(([id, label]) => { const layer = shownNodes.filter((node) => typeGroup(node) === id); return <section key={id} className="pi-topology-layer"><header><span>{label}</span><b>{layer.length}</b></header><div>{layer.length ? layer.map((node) => <button key={node.id} className={cls("pi-topology-node", selectedNode === node.id && "selected", selectedNode && !relatedIds.has(node.id) && "dimmed")} onClick={() => inspectNode(node)} title={`${node.type}: ${node.name}`}><small>{node.type.replaceAll("-", " ")}</small><b>{node.name}</b><span>{edges.filter((edge) => edge.from === node.id || edge.to === node.id).length} links</span></button>) : <p className="pi-layer-empty">No evidence in this layer</p>}</div></section>; })}</div>
      {selectedNode && <div className="pi-neighbor-summary"><b>{nodeById.get(selectedNode)?.name}</b><span>{shownEdges.length} direct evidence-backed relationships highlighted</span></div>}
    </div>}
    <div className="card"><div className="card-head"><div><h2>Evidence relationships</h2><p>{selectedNode ? "Showing direct relationships for the selected node." : "A text equivalent of the current topology, with full identifiers."}</p></div><span className="badge">{shownEdges.length}</span></div><div className="pi-table-scroll"><table className="tbl"><thead><tr><th>Relationship</th><th>From</th><th>To</th><th>Confidence</th></tr></thead><tbody>{shownEdges.map((edge, index) => <tr className="clk" key={index} onClick={() => onInspect(edge)}><td>{edge.type}</td><td><b>{nodeById.get(edge.from)?.name || edge.from}</b><small className="pi-cell-sub mono">{edge.from}</small></td><td><b>{nodeById.get(edge.to)?.name || edge.to}</b><small className="pi-cell-sub mono">{edge.to}</small></td><td>{Math.round((edge.confidence || 0) * 100)}%</td></tr>)}</tbody></table></div></div>
  </div>;
}

function PIFreshness({ overview, onInspect }) {
  if (!overview) return <PIEmpty icon="refresh" title="Loading freshness">Checking exact Git generations and external snapshots.</PIEmpty>;
  const repositories = overview.repositories || {};
  const sources = overview.sources || {};
  const repositoryRows = overview.repositoryRows || [];
  const sourceRows = overview.sourceRows || [];
  return <div className="grid pi-freshness-grid" style={{ gap: "var(--gap)" }}>
    <div className="card"><div className="card-head"><div><h2>Repository generations</h2><p>Remote default branch versus the exact indexed commit.</p></div><span className="badge">{repositories.current ?? "—"}/{repositories.total ?? "—"} current</span></div><div className="pi-table-scroll"><table className="tbl"><thead><tr><th>Repository</th><th>Branch</th><th>Remote</th><th>Indexed</th><th>Generation</th><th>Status</th></tr></thead><tbody>{repositoryRows.map((item) => <tr className="clk" key={item.repo} tabIndex="0" onKeyDown={(event) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); onInspect({ title: item.repo, ...item.freshness, projectId: item.projectId }); } }} onClick={() => onInspect({ title: item.repo, ...item.freshness, projectId: item.projectId })}><td><b>{item.repo}</b><small className="pi-cell-sub">{item.projectName}</small></td><td>{item.freshness?.defaultBranch || "—"}</td><td className="mono">{piShortSha(item.freshness?.remoteSha)}</td><td className="mono">{piShortSha(item.freshness?.indexedSha)}</td><td>{item.freshness?.generation || "—"}</td><td><PIStatus status={item.freshness?.fresh ? "fresh" : item.freshness?.status} /></td></tr>)}</tbody></table></div></div>
    <div className="card"><div className="card-head"><div><h2>Source snapshots</h2><p>Capture, expiry, completeness, and checksum for non-Git evidence.</p></div><span className="badge">{sources.fresh ?? "—"}/{sources.total ?? "—"} fresh</span></div><div className="pi-table-scroll"><table className="tbl"><thead><tr><th>Source</th><th>Producer</th><th>Captured</th><th>Expires</th><th>Snapshot</th><th>Status</th></tr></thead><tbody>{sourceRows.map((item) => <tr className="clk" key={item.sourceId} tabIndex="0" onKeyDown={(event) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); onInspect({ title: item.sourceId, ...item }); } }} onClick={() => onInspect({ title: item.sourceId, ...item })}><td><b>{item.sourceId}</b><small className="pi-cell-sub">{item.environment || "all environments"}</small></td><td>{item.producer || "—"}</td><td>{piWhen(item.capturedAt)}</td><td>{piWhen(item.expiresAt)}</td><td className="mono">{String(item.snapshotId || "—").slice(0, 18)}</td><td><PIStatus status={item.fresh ? "fresh" : item.status} /></td></tr>)}</tbody></table></div></div>
  </div>;
}

function PIDrift({ onInspect }) {
  const [data, setData] = useState(null); const [error, setError] = useState("");
  const load = useCallback(() => { setError(""); HERMES.intelligenceDrift().then(setData).catch((e) => setError(e.message)); }, []);
  useEffect(load, [load]);
  if (error) return <div className="card pi-alert bad"><Icon name="activity" /><div><b>Drift unavailable</b><p>{error}</p></div><button className="btn btn-ghost btn-sm" onClick={load}>Retry</button></div>;
  if (!data) return <PIEmpty icon="refresh" title="Loading drift">Reading deterministic documentation-review findings.</PIEmpty>;
  if (!data.findings?.length) return <PIEmpty icon="check" title="No deterministic drift findings">Current indexed generations have no broken documentation links or changed-code review candidates.</PIEmpty>;
  return <div className="card"><div className="card-head"><div><h2>Documentation review queue</h2><p>Findings are deterministic signals; an agent may explain them but cannot waive them.</p></div><span className="badge warn">{data.findings.length} findings</span></div><div className="pi-drift-list">{data.findings.map((item, index) => <button key={`${item.repository}:${index}`} className="pi-drift-row" onClick={() => onInspect({ title: item.kind, ...item })}><span className="glyph"><Icon name="file" size={16} /></span><span><b>{item.kind}</b><small>{item.repository}@{piShortSha(item.commitSha)} · {item.document || item.target || "repository"}</small></span><span className="badge">{Math.round((item.confidence || 0) * 100)}%</span><Icon name="chevron" size={15} /></button>)}</div></div>;
}

function PageProjectIntelligence({ toast }) {
  const initial = new URLSearchParams(window.location.search).get("tab");
  const [tab, setTab] = useState(PI_TABS.some((item) => item.id === initial) ? initial : "ask");
  const [overview, setOverview] = useState(null);
  const [error, setError] = useState("");
  const [refreshing, setRefreshing] = useState(false);
  const [selected, setSelected] = useState(null);
  const load = useCallback(async () => { setRefreshing(true); setError(""); try { setOverview(await HERMES.intelligenceOverview()); } catch (e) { setError(e.message || "Project Intelligence is unavailable"); } finally { setRefreshing(false); } }, []);
  useEffect(() => { load(); }, [load]);
  const changeTab = (id) => { setTab(id); const url = new URL(window.location.href); url.searchParams.set("tab", id); url.searchParams.delete("question"); window.history.replaceState({}, "", url); };
  const tabKey = (event, id) => {
    if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return;
    event.preventDefault();
    const index = PI_TABS.findIndex((item) => item.id === id);
    const next = event.key === "Home" ? 0 : event.key === "End" ? PI_TABS.length - 1 : (index + (event.key === "ArrowRight" ? 1 : -1) + PI_TABS.length) % PI_TABS.length;
    changeTab(PI_TABS[next].id);
    requestAnimationFrame(() => document.getElementById(`pi-tab-${PI_TABS[next].id}`)?.focus());
  };
  const repositorySummary = overview?.repositories || {};
  const sourceSummary = overview?.sources || {};
  return <div className="page pi-page">
    <div className="page-head pi-page-head"><div><span className="eyebrow">Portfolio knowledge</span><h1 className="page-title">Project Intelligence</h1><p className="page-sub">Ask across code, architecture, deployments, documentation, cloud inventory, and runtime evidence—with exact provenance.</p></div><div className="pi-overview-strip"><PIStatus status={error ? "unavailable" : overview?.status || "loading"} label={error ? "unavailable" : overview?.status || "loading"} /><span><b>{repositorySummary.current ?? "—"}</b>/{repositorySummary.total ?? "—"} repos</span><span><b>{sourceSummary.fresh ?? "—"}</b>/{sourceSummary.required || sourceSummary.total || "—"} sources</span><button className="icon-btn" onClick={load} disabled={refreshing} aria-label="Refresh dashboard metadata" title="Refresh dashboard metadata"><Icon name="refresh" size={15} /></button></div></div>
    {error && <div className="card pi-alert bad" role="alert"><Icon name="activity" /><div><b>Project Intelligence is unavailable</b><p>{error}. The rest of Sylar’s Work Manager remains available.</p></div><button className="btn btn-ghost btn-sm" onClick={load}>Retry</button></div>}
    <div className="pi-tabs" role="tablist" aria-label="Project Intelligence views">{PI_TABS.map((item) => <button id={`pi-tab-${item.id}`} key={item.id} className={cls("pi-tab", tab === item.id && "on")} role="tab" aria-selected={tab === item.id} aria-controls={`pi-panel-${item.id}`} tabIndex={tab === item.id ? 0 : -1} onKeyDown={(event) => tabKey(event, item.id)} onClick={() => changeTab(item.id)}>{item.label}</button>)}</div>
    <section id={`pi-panel-${tab}`} role="tabpanel" aria-labelledby={`pi-tab-${tab}`}>
      {tab === "ask" && <PIAsk overview={overview} toast={toast} onInspect={setSelected} />}
      {tab === "architecture" && <PIArchitecture overview={overview} onInspect={setSelected} />}
      {tab === "freshness" && <PIFreshness overview={overview} onInspect={setSelected} />}
      {tab === "drift" && <PIDrift onInspect={setSelected} />}
    </section>
    {selected && <PIProvenanceDrawer item={selected} onClose={() => setSelected(null)} />}
  </div>;
}

window.PageProjectIntelligence = PageProjectIntelligence;
