/* ============================================================
   gp-plan.jsx — PLAN stage: master list + detail orchestration.
   The core audit surface.
   ============================================================ */

var { useState, useEffect, useMemo } = React;

// ---- MASTER: day's plan grouped by strategy, with verdict dots ----
function PlanMaster({ decisions, selectedId, onSelect, summary }) {
  const groups = window.GP.STRATEGIES.map((s) => ({
    strat: s,
    items: decisions.filter((d) => d.strategy_id === s.id),
  }));

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }}>
      {/* health summary */}
      <div style={{ padding: "14px 16px", borderBottom: "1px solid var(--line)" }}>
        <Label style={{ fontSize: 10, letterSpacing: "0.18em" }}>Today's game plan · {window.GP.TODAY}</Label>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 8 }}>
          <Mono color="var(--fg)" size={26} weight={600}>{summary.total}</Mono>
          <Mono color="var(--fg-3)" size={11}>decisions</Mono>
          <div style={{ marginLeft: "auto", display: "flex", gap: 12 }}>
            <span><Mono color="var(--emerald)" size={15} weight={600}>{summary.verified}</Mono> <Label color="var(--fg-3)">verified</Label></span>
            <span><Mono color={summary.flagged ? "var(--rose)" : "var(--fg-3)"} size={15} weight={600}>{summary.flagged}</Mono> <Label color="var(--fg-3)">review</Label></span>
          </div>
        </div>
        <div style={{ marginTop: 10, display: "flex", height: 4, borderRadius: 2, overflow: "hidden", background: "var(--bg-2)" }}>
          <div style={{ width: (summary.verified / summary.total * 100) + "%", background: "var(--emerald)" }} />
          <div style={{ width: (summary.flagged / summary.total * 100) + "%", background: "var(--rose)" }} />
        </div>
      </div>

      <div style={{ flex: 1, overflowY: "auto", minHeight: 0 }}>
        {groups.map(({ strat, items }) => (
          <div key={strat.id}>
            <div style={{
              display: "flex", alignItems: "center", justifyContent: "space-between",
              padding: "10px 16px 6px", position: "sticky", top: 0,
              background: "var(--bg-1)", borderBottom: "1px solid var(--line-soft)", zIndex: 1,
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <Mono color="var(--indigo)" size={11} weight={600}>{strat.label}</Mono>
              </div>
              <Mono color="var(--fg-3)" size={9}>floor {(strat.floor * 100).toFixed(0)}% · {items.length} picks</Mono>
            </div>
            {items.map((d) => {
              const r = window.GP.verify.checkDecision(d);
              const rob = window.GP.verify.robustness(d);
              const sel = d.id === selectedId;
              return (
                <div key={d.id} onClick={() => onSelect(d.id)} style={{
                  display: "grid", gridTemplateColumns: "auto 1fr auto", alignItems: "center", gap: 10,
                  padding: "10px 16px", cursor: "pointer",
                  borderBottom: "1px solid var(--line-soft)",
                  background: sel ? "var(--bg-2)" : "transparent",
                  borderLeft: "2px solid " + (sel ? "var(--cyan)" : "transparent"),
                }}>
                  <VerdictDot verdict={r.verdict} size={7} pulse={r.verdict === "FLAGGED"} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <Mono color="var(--fg)" size={13} weight={600}>{d.asset.split("/")[0]}</Mono>
                      <Mono color="var(--fg-3)" size={9}>#{d.selection.rank} pick</Mono>
                    </div>
                    <div style={{ marginTop: 3, display: "flex", alignItems: "center", gap: 6 }}>
                      <Mono color="var(--fg-3)" size={9}>comp {d.winner.composite_score?.toFixed(3) ?? "—"}</Mono>
                      <span style={{ color: "var(--line-strong, #3f3f46)" }}>·</span>
                      <Mono color={rob.kind === "PLATEAU" ? "var(--emerald)" : rob.kind === "SPIKE" ? "var(--rose)" : rob.kind === "NARROW" ? "var(--amber)" : "var(--cyan)"} size={9}>{rob.kind.toLowerCase()}</Mono>
                    </div>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    {r.verdict === "FLAGGED"
                      ? <Pill kind="flagged">review</Pill>
                      : <Mono color="var(--emerald)" size={9}>#{r.winnerRank}/{r.validCount}</Mono>}
                  </div>
                </div>
              );
            })}
          </div>
        ))}
      </div>
    </div>
  );
}

// ---- DETAIL HEADER ----
function DetailHeader({ decision }) {
  const a = window.GP.U(decision.asset);
  const strat = window.GP.STRATEGIES.find((s) => s.id === decision.strategy_id);
  const age = window.GP.fmt.ago(decision.sweep.finished_at, window.GP.NOW);
  return (
    <div style={{ padding: "16px 16px 14px", borderBottom: "1px solid var(--line)" }}>
      <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12 }}>
        <div>
          <div style={{ display: "flex", alignItems: "baseline", gap: 12 }}>
            <span style={{ fontFamily: "var(--head)", fontSize: 30, fontWeight: 600, color: "var(--fg)", letterSpacing: "-0.01em" }}>{decision.asset}</span>
            <Mono color="var(--indigo)" size={12} weight={500}>{decision.strategy_class}</Mono>
            <Pill kind="accent">{decision.group_id}</Pill>
          </div>
          <div style={{ marginTop: 8, display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
            <RegimeTag regime={decision.selection.regime} />
            {decision.selection.tags.slice(0, 3).map((t) => (
              <Mono key={t} color="var(--fg-3)" size={9} style={{ letterSpacing: "0.08em" }}>{t}</Mono>
            ))}
          </div>
        </div>
        <div style={{ textAlign: "right" }}>
          <Mono color="var(--fg)" size={18} weight={600}>{window.GP.fmt.price(a.px)}</Mono>
          <div style={{ marginTop: 2 }}>
            <Mono color={a.chg > 0 ? "var(--emerald)" : "var(--rose)"} size={11}>{window.GP.fmt.signedPct(a.chg)}</Mono>
          </div>
        </div>
      </div>
      <div style={{ marginTop: 12, display: "flex", gap: 18, flexWrap: "wrap" }}>
        <span><Label>objective</Label> <Mono color="var(--cyan)" size={10}>{decision.sweep_objective}</Mono></span>
        <span><Label>grid</Label> <Mono color="var(--fg-2)" size={10}>{decision.sweep.sampled} of {decision.sweep.coarse_grid_size} combos</Mono></span>
        <span><Label>bars</Label> <Mono color="var(--fg-2)" size={10}>{decision.bar_count}</Mono></span>
        <span><Label>swept</Label> <Mono color="var(--fg-2)" size={10}>{window.GP.fmt.time(decision.sweep.finished_at)}Z · {age} ago</Mono></span>
      </div>
    </div>
  );
}

// ---- WINNER + selected-candidate comparison ----
function WinnerCompare({ decision, selectedIdx }) {
  const strat = window.GP.STRATEGIES.find((s) => s.id === decision.strategy_id);
  const winner = decision.winner;
  const sel = selectedIdx != null ? decision.sweep.candidates[selectedIdx] : null;
  const isWinnerSel = sel && JSON.stringify(sel.params) === JSON.stringify(winner.params);
  const keys = Object.keys(strat.paramSpace);
  const METRICS = window.GP.verify.METRICS;

  const Col = ({ title, cand, accent }) => (
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
        <Mono color={accent} size={10} weight={600} style={{ letterSpacing: "0.12em" }}>{title}</Mono>
      </div>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 10 }}>
        {keys.map((k) => {
          const changed = sel && !isWinnerSel && cand !== winner && cand.params[k] !== winner.params[k];
          return <ParamChip key={k} k={k} v={cand.params[k]} changed={cand !== winner && sel && cand.params[k] !== winner.params[k]} />;
        })}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "6px 14px" }}>
        {METRICS.map((m) => (
          <div key={m.key} style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
            <Label>{m.short}</Label>
            <MetricVal metricKey={m.key} value={cand[m.key]} size={11} />
          </div>
        ))}
      </div>
    </div>
  );

  return (
    <div>
      <SectionBar num="02" title={sel && !isWinnerSel ? "Winner vs. selected alternative" : "Winning configuration"} right={
        sel && !isWinnerSel ? <Pill kind="warn">comparing — amber = differs</Pill> : <Pill kind="winner" dot>committed to plan</Pill>
      } />
      <div style={{ padding: "14px 16px", display: "flex", gap: 22 }}>
        <Col title="◆ WINNER" cand={winner} accent="var(--emerald)" />
        {sel && !isWinnerSel && (
          <>
            <div style={{ width: 1, background: "var(--line)" }} />
            <Col title="○ SELECTED ALT" cand={sel} accent="var(--cyan)" />
          </>
        )}
      </div>
    </div>
  );
}

// ---- PLAN VIEW (master + detail) ----
function PlanView({ flagStyle, initialId }) {
  const decisions = window.GP.DATA.decisions;
  const summary = useMemo(() => window.GP.verify.summary(decisions), [decisions]);
  const [selectedId, setSelectedId] = useState(initialId || decisions[0].id);
  const [metricKey, setMetricKey] = useState("composite_score");
  const [selCand, setSelCand] = useState(null);
  const [showRejected, setShowRejected] = useState(false);

  // follow jumps from other stages
  useEffect(() => { if (initialId) setSelectedId(initialId); }, [initialId]);

  const decision = decisions.find((d) => d.id === selectedId);
  const result = useMemo(() => window.GP.verify.checkDecision(decision), [decision]);

  useEffect(() => { setSelCand(null); setShowRejected(false); }, [selectedId]);

  return (
    <div style={{ position: "absolute", inset: 0, display: "flex" }}>
      <div style={{ flex: "0 0 330px", borderRight: "1px solid var(--line)", minHeight: 0, overflow: "hidden", background: "var(--bg-1)", display: "flex", flexDirection: "column" }}>
        <PlanMaster decisions={decisions} selectedId={selectedId} onSelect={setSelectedId} summary={summary} />
      </div>
      <div style={{ flex: 1, overflowY: "auto", minHeight: 0, minWidth: 0 }}>
        <DetailHeader decision={decision} />
        <VerdictBanner result={result} decision={decision} flagStyle={flagStyle} />
        <LinkageChecks result={result} />
        <WinnerCompare decision={decision} selectedIdx={selCand} />
        <CandidateScale
          decision={decision} metricKey={metricKey} setMetricKey={setMetricKey}
          selected={selCand} onSelect={setSelCand}
          showRejected={showRejected} setShowRejected={setShowRejected}
        />
        <RobustnessPanel decision={decision} />
        <div style={{ padding: "10px 16px 30px" }}>
          <Mono color="var(--fg-3)" size={9} style={{ lineHeight: 1.6 }}>
            Source · data/daily_briefing.json → decisions[{decisions.indexOf(decision)}] · serialized by centaur.optimizer._export_daily_briefing (LL-049).
            All checks recomputed client-side from the raw candidate field.
          </Mono>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PlanView, PlanMaster, DetailHeader, WinnerCompare });
