/* ============================================================
   gp-exec.jsx — EXECUTION stage: recorded plan vs. live broker fills

   Sources (all live, all degrade-or-die honest):
     - GET /api/positions   → live filled side (market value, unrealized P/L)
     - GET /api/orders/open → pending limit/stop legs not yet filled
     - GET /api/trades      → the engine's RECORDED plan per order
                              (target_weight / drift / notional_usd persisted
                              by centaur/ledger.py — surfaced verbatim, never
                              re-derived).

   When the broker is not connected (Alpaca creds absent → 500) or the ledger
   is empty, the rows simply thin out and an honest banner explains why. We
   never fabricate a target weight, planned size, or drift the data lacks.
   ============================================================ */

var { useState: eS } = React;

const EXEC_STATUS = {
  FILLED:  { kind: "verified", label: "filled" },
  PENDING: { kind: "warn",     label: "pending" },
  HELD:    { kind: "accent",   label: "held" },
  SKIPPED: { kind: "rejected", label: "skipped" },
  FAILED:  { kind: "flagged",  label: "failed" },
  UNKNOWN: { kind: "neutral",  label: "awaiting" },
};

function BrokerBadge({ isPaper }) {
  if (isPaper == null) return null;
  const live = !isPaper;
  return (
    <span style={{
      fontFamily: "var(--mono)", fontSize: 8, letterSpacing: "0.12em", fontWeight: 700,
      padding: "1px 5px", borderRadius: 2, textTransform: "uppercase",
      color: live ? "var(--rose)" : "var(--amber)",
      background: live ? "color-mix(in oklab, var(--rose) 14%, transparent)"
                       : "color-mix(in oklab, var(--amber) 14%, transparent)",
    }}>{live ? "live" : "paper"}</span>
  );
}

function ExecRightCell({ children, color = "var(--fg-2)", size = 11 }) {
  return <Mono color={color} size={size} style={{ textAlign: "right", justifySelf: "end" }}>{children}</Mono>;
}

function ExecutionView({ onJump }) {
  const exec = window.GP.DATA.execution;
  const meta = window.GP.DATA.execMeta || {};
  const decisions = window.GP.DATA.decisions;
  const [expanded, setExpanded] = eS(null);

  const totalPlanned = exec.reduce((s, e) => s + (e.plannedUsd || 0), 0);
  const totalFilled = exec.reduce((s, e) => s + (e.filledUsd || 0), 0);
  const filledCount = exec.filter((e) => e.status === "FILLED" || e.status === "HELD").length;
  const pending = exec.filter((e) => e.status === "PENDING").length;

  const GRID = "20px 1.2fr 1.1fr 0.7fr 0.9fr 0.9fr 0.9fr 1fr auto";

  return (
    <div style={{ height: "100%", overflowY: "auto", padding: "0 0 30px" }}>
      <div style={{ padding: "18px 20px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 14 }}>
        <div>
          <span style={{ fontFamily: "var(--head)", fontSize: 20, fontWeight: 600, color: "var(--fg)" }}>Execution</span>
          <Mono color="var(--fg-3)" size={10} style={{ marginLeft: 12 }}>recorded plan vs. live broker fills</Mono>
        </div>
        <div style={{ display: "flex", gap: 26 }}>
          {[
            ["planned", window.GP.fmt.moneyK(totalPlanned || null), "var(--fg)"],
            ["deployed", window.GP.fmt.moneyK(totalFilled || null), "var(--cyan)"],
            ["filled", `${filledCount}/${exec.length}`, "var(--emerald)"],
            ["pending", pending, pending ? "var(--amber)" : "var(--fg-3)"],
          ].map(([l, v, c]) => (
            <div key={l}><Mono color={c} size={20} weight={600}>{v}</Mono><div><Label>{l}</Label></div></div>
          ))}
        </div>
      </div>

      {/* honest link state — explains an empty/thin table instead of faking fills */}
      {!meta.brokerUp && (
        <div style={{ margin: "12px 20px 0", padding: "9px 12px", background: "color-mix(in oklab, var(--amber) 9%, transparent)", borderLeft: "2px solid var(--amber)", borderRadius: 2 }}>
          <Mono color="var(--amber)" size={10} style={{ lineHeight: 1.5 }}>
            Broker not connected — live positions & open orders unavailable ({meta.reason || "credentials absent on server"}).
            {meta.ledgerUp ? " Showing the recorded ledger plan only." : " Ledger feed also unavailable."}
          </Mono>
        </div>
      )}

      {exec.length === 0 ? (
        <div style={{ display: "grid", placeItems: "center", padding: "60px 24px" }}>
          <div style={{ textAlign: "center", maxWidth: 440 }}>
            <Mono color="var(--fg-2)" size={13} weight={600} style={{ letterSpacing: "0.1em" }}>
              {!meta.brokerUp && !meta.ledgerUp ? "NO EXECUTION LINK" : "NO EXECUTION ACTIVITY"}
            </Mono>
            <Mono color="var(--fg-3)" size={11} style={{ marginTop: 12, display: "block", lineHeight: 1.7 }}>
              {!meta.brokerUp && !meta.ledgerUp
                ? "Neither the broker nor the order ledger is reachable. Connect Alpaca credentials on the server and seed the ledger to populate plan-vs-fill."
                : "No positions, open orders, or ledger orders match today's decisions yet. Rows appear here as the engine submits the committed plan."}
            </Mono>
          </div>
        </div>
      ) : (
        <div style={{ padding: "0 20px" }}>
          <div style={{ display: "grid", gridTemplateColumns: GRID, gap: 12, padding: "12px 8px 8px", borderBottom: "1px solid var(--line)" }}>
            {["", "Asset", "Strategy", "Side", "Target wt", "Planned", "Filled", "Unreal P/L", "Status"].map((h, i) => (
              <Label key={i} style={{ textAlign: i >= 4 && i <= 7 ? "right" : "left", justifySelf: i >= 4 && i <= 7 ? "end" : "start" }}>{h}</Label>
            ))}
          </div>
          {exec.map((e) => {
            const d = e.decisionId ? decisions.find((x) => x.id === e.decisionId) : null;
            const r = d ? window.GP.verify.checkDecision(d) : null;
            const st = EXEC_STATUS[e.status] || EXEC_STATUS.UNKNOWN;
            const isOpen = expanded === e.symbol;
            const fillFrac = e.plannedUsd && e.filledUsd != null ? e.filledUsd / e.plannedUsd : null;
            return (
              <div key={e.symbol} style={{ borderBottom: "1px solid var(--line-soft)" }}>
                <div onClick={() => setExpanded(isOpen ? null : e.symbol)} style={{
                  display: "grid", gridTemplateColumns: GRID, gap: 12,
                  padding: "10px 8px", alignItems: "center", cursor: "pointer",
                }}>
                  <Mono color="var(--fg-3)" size={10}>{isOpen ? "▾" : "▸"}</Mono>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <Mono color="var(--fg)" size={12} weight={600}>{e.symbol.split("/")[0]}</Mono>
                    <BrokerBadge isPaper={e.isPaper} />
                    {r && <VerdictDot verdict={r.verdict} size={6} />}
                  </div>
                  <Mono color="var(--indigo)" size={10}>{d ? d.strategy_class : "—"}</Mono>
                  <Mono color={e.side === "SELL" ? "var(--rose)" : e.side === "BUY" ? "var(--emerald)" : "var(--fg-3)"} size={10} weight={600}>{e.side || "—"}</Mono>
                  <ExecRightCell>{e.targetWeight == null ? "—" : (e.targetWeight * 100).toFixed(1) + "%"}</ExecRightCell>
                  <ExecRightCell>{window.GP.fmt.moneyK(e.plannedUsd)}</ExecRightCell>
                  <ExecRightCell color="var(--fg)">{window.GP.fmt.moneyK(e.filledUsd)}</ExecRightCell>
                  <ExecRightCell color={e.unrealizedPl == null ? "var(--fg-3)" : e.unrealizedPl >= 0 ? "var(--emerald)" : "var(--rose)"}>
                    {e.unrealizedPl == null ? "—" : window.GP.fmt.money(e.unrealizedPl)}
                  </ExecRightCell>
                  <div style={{ justifySelf: "start" }}><Pill kind={st.kind} dot={e.status === "FILLED"}>{st.label}</Pill></div>
                </div>
                {isOpen && (
                  <div style={{ padding: "4px 8px 16px 40px", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 22 }}>
                    {/* plan adherence — only meaningful when a recorded plan exists */}
                    <div>
                      <Label style={{ display: "block", marginBottom: 8 }}>Plan adherence</Label>
                      {e.plannedUsd == null ? (
                        <Mono color="var(--fg-3)" size={10} style={{ lineHeight: 1.5 }}>
                          No recorded order for {e.symbol} — this row is a live broker
                          {e.filledUsd != null ? " holding" : " state"} with no engine plan to compare against.
                        </Mono>
                      ) : (
                        <>
                          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                            <Mono color="var(--fg-3)" size={9} style={{ width: 54 }}>planned</Mono>
                            <div style={{ flex: 1 }}><Bar frac={1} color="var(--bg-3)" height={8} /></div>
                            <Mono color="var(--fg-2)" size={10} style={{ width: 56, textAlign: "right" }}>{window.GP.fmt.moneyK(e.plannedUsd)}</Mono>
                          </div>
                          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                            <Mono color="var(--fg-3)" size={9} style={{ width: 54 }}>filled</Mono>
                            <div style={{ flex: 1 }}><Bar frac={fillFrac == null ? 0 : fillFrac} color={fillFrac != null && fillFrac > 0.95 ? "var(--emerald)" : "var(--amber)"} height={8} /></div>
                            <Mono color="var(--fg)" size={10} style={{ width: 56, textAlign: "right" }}>{fillFrac == null ? "—" : (fillFrac * 100).toFixed(0) + "%"}</Mono>
                          </div>
                          <div style={{ marginTop: 10, display: "flex", gap: 18, flexWrap: "wrap" }}>
                            <span><Label>drift</Label> <Mono color="var(--fg)" size={10}>{e.drift == null ? "—" : (e.drift * 100).toFixed(2) + "%"}</Mono></span>
                            <span><Label>mark</Label> <Mono color="var(--fg)" size={10}>{window.GP.fmt.price(e.currentPx)}</Mono></span>
                            {e.regime && <span><Label>regime</Label> <RegimeTag regime={e.regime} small /></span>}
                            {e.orderTs && <span><Label>logged</Label> <Mono color="var(--fg-2)" size={10}>{window.GP.fmt.time(e.orderTs)}Z</Mono></span>}
                          </div>
                          {e.orderStatus === "FAILED" && (
                            <div style={{ marginTop: 12, padding: "8px 10px", background: "color-mix(in oklab, var(--rose) 9%, transparent)", borderLeft: "2px solid var(--rose)", borderRadius: 2 }}>
                              <Mono color="var(--rose)" size={10}>Order FAILED at the broker — recorded plan was not deployed.</Mono>
                            </div>
                          )}
                        </>
                      )}
                    </div>
                    {/* open orders + audit cross-link */}
                    <div>
                      <Label style={{ display: "block", marginBottom: 8 }}>Open orders ({e.openOrders.length})</Label>
                      {e.openOrders.length === 0 && <Mono color="var(--fg-3)" size={10}>no resting orders at the broker</Mono>}
                      {e.openOrders.map((o, i) => (
                        <div key={o.id || i} style={{ display: "grid", gridTemplateColumns: "44px 1fr 1fr 1fr", gap: 10, padding: "4px 0", borderBottom: "1px solid var(--line-soft)" }}>
                          <Mono color={o.side === "SELL" ? "var(--rose)" : "var(--emerald)"} size={10} weight={600}>{o.side}</Mono>
                          <Mono color="var(--fg-2)" size={10} style={{ textAlign: "right" }}>{o.qty == null ? "—" : o.qty}</Mono>
                          <Mono color="var(--fg-2)" size={10} style={{ textAlign: "right" }}>{window.GP.fmt.price(o.limit_price)}</Mono>
                          <Mono color="var(--fg-3)" size={10} style={{ textAlign: "right" }}>{window.GP.fmt.time(o.submitted_at)}Z</Mono>
                        </div>
                      ))}
                      {d && (
                        <button onClick={(ev) => { ev.stopPropagation(); onJump(e.decisionId); }} style={{ marginTop: 10, background: "transparent", border: "1px solid var(--line)", borderRadius: 2, padding: "5px 10px", cursor: "pointer", fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.12em", color: "var(--cyan)", textTransform: "uppercase" }}>
                          open audit →
                        </button>
                      )}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ExecutionView });
