/* ============================================================
   Lineage — Agents view (sessions, incl. orphans) + Session detail
   The agent-first counterpart to History. A session is stored once;
   here you see every session — including orphans that cost money but
   produced no commit — and can manually link an orphan to a commit.
   ============================================================ */
const { useState: useStateS, useEffect: useEffectS } = React;

function sessionOutcome(s, links) {
  const n = window.commitsForSession(s.id, links).all.length;
  if (n > 0) return { kind: "shipped", label: n + " commit" + (n > 1 ? "s" : "") };
  if (s.outcome === "abandoned") return { kind: "abandoned", label: "abandoned" };
  if (s.outcome === "superseded") return { kind: "superseded", label: "draft · unlinked" };
  return { kind: "explored", label: "no output" };
}

/* ---- reverse picker: orphan session → choose a commit ---- */
function CommitPicker({ session, links, onPick, onClose }) {
  useEffectS(() => {
    const h = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [onClose]);

  const candidates = window.LINEAGE_COMMITS.filter(c => !c.sessionId && !links[c.hash] && !c.merge);
  return (
    <>
      <div className="lp-scrim" onClick={onClose} />
      <div className="lp" role="dialog" aria-modal="true">
        <div className="lp-head">
          <div>
            <div className="lp-title">Link this session to a commit</div>
            <div className="lp-sub mono">{session.agent.name} · {window.sessionTask(session).slice(0, 52)}…</div>
          </div>
          <button className="d-close" onClick={onClose}><Icon name="close" size={16} /></button>
        </div>
        <div className="lp-note">Pick the commit this session’s work ended up in. Only unattributed commits are shown.</div>
        <div className="lp-list">
          {candidates.map(c => (
            <button key={c.hash} className="lp-row" onClick={() => onPick(c.hash)}>
              <span className="lp-row-ic lp-row-ic-commit"><Icon name="commit" size={12} /></span>
              <div className="lp-row-body">
                <div className="lp-row-top">
                  <span className="lp-row-agent">{c.message}</span>
                </div>
                <div className="lp-row-task mono">{c.hash} · {c.author.name} · {c.day}</div>
              </div>
              <span className="lp-row-cost mono"><span className="add">+{c.add}</span><span className="del">−{c.del}</span></span>
            </button>
          ))}
          {candidates.length === 0 && <div className="lp-empty">No unattributed commits to link.</div>}
        </div>
      </div>
    </>
  );
}

/* ====================  SESSION DETAIL  ==================== */
function SessionDetail({ sid, links, linkActions, go, onBack }) {
  const [picking, setPicking] = useStateS(false);
  useEffectS(() => {
    const h = (e) => { if (e.key === "Escape" && !picking) onBack(); };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [onBack, picking]);

  const s = window.LINEAGE_SESSIONS[sid];
  const produced = window.commitsForSession(sid, links);
  const orphan = produced.all.length === 0;
  const participants = window.sessionParticipants(s);
  const turns = window.sessionTurns(s);
  const repos = window.sessionRepos(sid, links);

  return (
    <div className="cd">
      <div className="cd-topbar">
        <button className="cd-back" onClick={onBack}><Icon name="chevron" size={14} style={{ transform: "rotate(180deg)" }} /> Agents</button>
        <span className="cd-branch mono"><Icon name="branch" size={12} />{s.branch}</span>
      </div>

      <div className="cd-scroll">
        <div className="cd-inner">
          <header className="cd-head">
            <div className="sd-kind mono">
              <Icon name="spark" size={12} /> AGENT SESSION
              {s.global && <span className="sd-global"><Icon name="graph" size={11} />global · multi-repo</span>}
            </div>
            <h1 className="cd-message sd-message">{window.sessionTask(s)}</h1>
            <div className="cd-meta">
              <span className="sd-agent"><span className="cm-agent-ic"><Icon name="spark" size={11} /></span>{s.agent.name}</span>
              <span className="model-chip mono">{s.agent.model}</span>
              {repos.map(r => <RepoBadge key={r} name={r} />)}
            </div>
          </header>

          {/* who took part — resume / handoff story */}
          {(participants.length > 0) && (
            <div className="sd-people">
              <span className="sd-people-label mono">{turns} turn{turns > 1 ? "s" : ""}</span>
              <div className="sd-people-list">
                {participants.map((p, i) => (
                  <React.Fragment key={p.name}>
                    {i > 0 && <Icon name="arrow" size={13} style={{ color: "var(--tx-4)" }} />}
                    <span className="sd-person">
                      <Avatar name={p.name} color={p.color} size={18} />{p.name}
                      <span className="sd-person-role">{i === 0 ? "started" : "resumed"}</span>
                    </span>
                  </React.Fragment>
                ))}
              </div>
              {window.sessionResumed(s) && <span className="sd-resumed-tag mono"><Icon name="branch" size={11} />handed off</span>}
            </div>
          )}

          <div className="cd-session-bar">
            <div className="csb-left">
              <span className="csb-label mono">RUN COST</span>
              <span className="csb-trigger">{s.day} · {fmtTime(s.ts)}</span>
            </div>
            <div className="csb-stats mono">
              <span title="wall time"><Icon name="clock" size={12} />{fmtDur(s.duration)}</span>
              <span title="tokens in"><Icon name="spark" size={12} />{fmtTok(s.tokens.in + s.tokens.out)} tok</span>
              <span title="cache read">{fmtTok(s.tokens.cache)} cache</span>
              <span className="csb-div" />
              <span title="cost" className="csb-cost"><Icon name="coin" size={12} />{fmtUSD(s.cost)}</span>
            </div>
          </div>

          {/* commits produced — or orphan state with manual link */}
          {orphan ? (
            <div className={"orphan-card orphan-" + (s.outcome || "explored")}>
              <div className="orphan-top">
                <span className="orphan-badge mono"><Icon name="dot" size={11} />NO COMMIT</span>
                <span className="orphan-outcome">{
                  s.outcome === "abandoned" ? "Abandoned" :
                  s.outcome === "superseded" ? "Superseded — handed to a human" :
                  "Explored — no code change"
                }</span>
                {s.repo && <RepoBadge name={s.repo} />}
              </div>
              <p className="orphan-note">{s.note}</p>
              <div className="orphan-actions">
                <button className="attr-link-btn" onClick={() => setPicking(true)}>
                  <Icon name="link" size={14} /> Link this session to a commit
                </button>
                <span className="orphan-spend mono">{fmtUSD(s.cost)} spent · 0 committed</span>
              </div>
            </div>
          ) : (
            <div className="sib sib-produced">
              <div className="sib-head">
                <Icon name="commit" size={13} style={{ color: "var(--agent-2)" }} />
                Commits from this session
                <span className="sib-count mono">{produced.all.length}</span>
                {repos.length > 1 && <span className="sib-xrepo mono">across {repos.length} repos</span>}
              </div>
              <div className="sib-list">
                {produced.all.map(c => {
                  const isManual = !c.sessionId && links[c.hash] === sid;
                  return (
                    <button key={c.hash} className="sib-row" onClick={() => go.commit(c.hash)}>
                      <RepoBadge name={c.repo} />
                      <span className="sib-hash mono">{c.hash}</span>
                      <span className="sib-msg">{c.message}</span>
                      {isManual && <span className="sib-manual mono"><Icon name="link" size={10} />linked</span>}
                      <span className="sib-stat mono"><span className="add">+{c.add}</span><span className="del">−{c.del}</span></span>
                      <Icon name="arrow" size={13} style={{ color: "var(--tx-4)" }} />
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          <SessionBody session={s} />
        </div>
      </div>

      {picking && (
        <CommitPicker
          session={s}
          links={links}
          onClose={() => setPicking(false)}
          onPick={(hash) => { linkActions.link(hash, sid); setPicking(false); }}
        />
      )}
    </div>
  );
}
window.SessionDetail = SessionDetail;

/* ====================  AGENTS VIEW (session list)  ==================== */
function AgentsView({ links, onOpen, repo, setRepo }) {
  let sessions = window.sessionList().slice().sort((a, b) => (a.ts < b.ts ? 1 : -1));
  if (repo !== "all") {
    sessions = sessions.filter(s => window.sessionRepos(s.id, links).indexOf(repo) !== -1);
  }
  const groups = [];
  let cur = null;
  sessions.forEach(s => {
    if (!cur || cur.day !== s.day) { cur = { day: s.day, items: [] }; groups.push(cur); }
    cur.items.push(s);
  });

  const orphanSessions = sessions.filter(s => window.isOrphan(s.id, links));
  const orphanSpend = orphanSessions.reduce((n, s) => n + s.cost, 0);
  const totalSpend = sessions.reduce((n, s) => n + s.cost, 0);
  const orphanPct = totalSpend ? Math.round((orphanSpend / totalSpend) * 100) : 0;

  return (
    <div className="history">
      <div className="history-inner">
        <div className="history-head">
          <div className="history-title">
            <h2>Agent sessions</h2>
            <span className="history-sub mono">{sessions.length} sessions · {orphanSessions.length} orphaned (no commit) · {repo === "all" ? "all repositories" : repo}</span>
          </div>
          <div className="agents-spend">
            <div className="aspend-row mono">
              <span className="aspend-total">{fmtUSD0(totalSpend)}</span>
              <span className="aspend-label">total spend</span>
            </div>
            <div className="aspend-bar"><span style={{ width: (100 - orphanPct) + "%" }} /></div>
            <div className="aspend-legend mono">
              <span><span className="lg-dot" style={{ background: "var(--agent)" }} />{fmtUSD0(totalSpend - orphanSpend)} shipped</span>
              <span><span className="lg-dot" style={{ background: "var(--cost)" }} />{fmtUSD0(orphanSpend)} no output</span>
            </div>
          </div>
        </div>

        {repo !== "all" && (
          <div className="scope-note">
            <RepoBadge name={repo} />
            <span>Sessions that touched this repository.</span>
            <button className="scope-clear" onClick={() => setRepo("all")}>View all</button>
          </div>
        )}

        <div className="commits">
          {groups.map((g, gi) => (
            <div className="cm-group" key={gi}>
              <div className="cm-day">
                <span className="cm-day-label">{g.day}</span>
                <span className="cm-day-rule" />
              </div>
              <div className="cm-list">
                {g.items.map(s => {
                  const oc = sessionOutcome(s, links);
                  const isOrphan = oc.kind !== "shipped";
                  const repos = window.sessionRepos(s.id, links);
                  const turns = window.sessionTurns(s);
                  const resumed = window.sessionResumed(s);
                  return (
                    <div key={s.id} className={"cm-row se-row" + (isOrphan ? " se-orphan" : "")} onClick={() => onOpen(s.id)}>
                      <span className={"se-dot se-dot-" + oc.kind} />
                      <div className="cm-body">
                        <div className="se-top">
                          <span className="se-agent">{s.agent.name}</span>
                          <span className="model-chip mono">{s.agent.model}</span>
                          {s.global && <span className="se-global mono"><Icon name="graph" size={10} />global</span>}
                          <span className={"se-outcome se-outcome-" + oc.kind + " mono"}>{oc.label}</span>
                          {resumed && <span className="se-resumed mono"><Icon name="branch" size={10} />resumed</span>}
                        </div>
                        <div className="se-task">{window.sessionTask(s)}</div>
                        <div className="se-foot">
                          {repos.map(r => <RepoBadge key={r} name={r} />)}
                          {turns > 1 && <span className="se-turns mono">{turns} turns</span>}
                        </div>
                      </div>
                      <div className="cm-right">
                        <span className="se-dur mono"><Icon name="clock" size={11} />{fmtDur(s.duration)}</span>
                        <span className={"se-cost mono" + (isOrphan ? " se-cost-orphan" : "")}><Icon name="coin" size={11} />{fmtUSD(s.cost)}</span>
                        <span className="cm-time mono">{fmtTime(s.ts)}</span>
                        <Icon name="chevron" size={13} style={{ color: "var(--tx-4)" }} />
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
window.AgentsView = AgentsView;
