import React from "react";
import { Zap, Box, ArrowRight, CornerDownRight, AlertTriangle, Terminal } from "lucide-react";
import { C, FD, FM, fmt, toolIcon } from "../theme.js";
import { Bar, PanelTitle, GeneratedTag, BinaryRow } from "./Primitives.jsx";
import { turnProse } from "../useAnalysis.js";

// RIGHT panel. Mirrors the Elastic "powershell.exe detail" idea: full execution
// detail of the selected node. Three states below.

export function SessionDetail({ session }) {
  const { tokens } = session;
  const ctx = session.context;
  return (
    <div style={{ overflowY: "auto", padding: 16 }}>
      <PanelTitle icon={Zap} text="SESSION TOKENS (CUMULATIVE)" />
      <Bar label="cache re-reads" v={tokens.cacheRead} max={tokens.cacheRead} c={C.orange} note="summed across every round-trip — the cost driver, not window size" />
      <Bar label="cache write" v={tokens.cacheCreate} max={tokens.cacheRead} c={C.amber} />
      <Bar label="generated" v={tokens.out} max={tokens.cacheRead} c={C.cyan} />
      <Bar label="fresh input" v={tokens.in} max={tokens.cacheRead} c={C.blue} />
      <div style={{ fontSize: 11.5, color: C.text2, marginTop: 10, lineHeight: 1.55 }}>
        Cache re-reads are <b style={{ color: C.orange }}>~{Math.round(tokens.cacheRead / Math.max(1, tokens.out))}×</b> generated — cumulative, so they vastly exceed the window. Spend tracks tool-call iterations, not answer length.
      </div>
      {ctx && (
        <div style={{ fontSize: 11.5, color: C.text2, marginTop: 10, lineHeight: 1.55, background: C.black, border: `1px solid ${C.border}`, borderRadius: 7, padding: "8px 10px" }}>
          Peak context window: <b style={{ color: (ctx.peakPct || 0) >= 0.8 ? C.amber : C.cyan }}>{fmt(ctx.peak)} / {fmt(ctx.limit)}</b> ({Math.round((ctx.peakPct || 0) * 100)}%) — the fuel gauge, bounded by the window. {ctx.compactions?.length ? `${ctx.compactions.length} compaction(s).` : "No compactions."}
        </div>
      )}

      <PanelTitle icon={ArrowRight} text="WHO DROVE THE WORK" mt />
      <CausalitySplit direct={session.direct} indirect={session.indirect} />
      <div style={{ fontSize: 11, color: C.muted, marginTop: 8, lineHeight: 1.5 }}>
        {Math.round((100 * session.indirect) / Math.max(1, session.direct + session.indirect))}% of tool calls were triggered by the agent's own prior output (proven value-flow).
      </div>
    </div>
  );
}

export function TurnDetail({ turn, narrated, binaries }) {
  const { tokens } = turn;
  const prose = turnProse(narrated, turn.i);
  // binaries (real tools behind Bash/npx) that fired in THIS turn — filtered from
  // the session-level list by the turns each appeared in.
  const turnBins = (binaries || []).filter((b) => (b.turns || []).includes(turn.i));
  const a = turn.indirect > turn.direct * 1.5;
  const deterministic = [
    `This query set off ${turn.reqs} model round-trip${turn.reqs !== 1 ? "s" : ""} and ${turn.tools.length} tool call${turn.tools.length !== 1 ? "s" : ""}.`,
    turn.tools.length
      ? a
        ? `${turn.indirect} (${Math.round((100 * turn.indirect) / turn.tools.length)}%) were driven by earlier tool output, not your message.`
        : `${turn.direct} came from your instruction; ${turn.indirect} followed from earlier output.`
      : "",
    `Cost is dominated by cache re-reads — ${fmt(tokens.cacheRead)} cached tokens reloaded (cumulative across round-trips), vs ${fmt(tokens.out)} generated.`,
    turn.ctxPeak ? `The live context window peaked at ${fmt(turn.ctxPeak)} during this turn (point-in-time, not cumulative).` : "",
  ].filter(Boolean).join(" ");

  return (
    <div style={{ overflowY: "auto", padding: 16 }}>
      <PanelTitle icon={Zap} text="WHY THESE TOKENS" />
      {prose ? (
        <div style={{ marginTop: 10 }}>
          <div style={{ marginBottom: 6 }}><GeneratedTag cites={`turn ${turn.i}`} /></div>
          <div style={{ fontSize: 13, color: C.text2, lineHeight: 1.6 }}>{prose}</div>
        </div>
      ) : (
        <div style={{ fontSize: 13, color: C.text2, lineHeight: 1.6, marginTop: 10 }}>{deterministic}</div>
      )}

      <PanelTitle icon={Box} text="TOKEN BREAKDOWN (CUMULATIVE)" mt />
      <Bar label="cache re-reads" v={tokens.cacheRead} max={tokens.cacheRead} c={C.orange} note="volume = long tool loops · summed across round-trips" />
      <Bar label="cache write" v={tokens.cacheCreate} max={tokens.cacheRead} c={C.amber} />
      <Bar label="generated" v={tokens.out} max={tokens.cacheRead} c={C.cyan} />
      <Bar label="fresh input" v={tokens.in} max={tokens.cacheRead} c={C.blue} />

      <PanelTitle icon={ArrowRight} text="CAUSALITY SPLIT" mt />
      <CausalitySplit direct={turn.direct} indirect={turn.indirect} />
      <div style={{ fontSize: 11, color: C.muted, marginTop: 8, lineHeight: 1.5 }}>
        Indirect = the tool's input appeared verbatim in an earlier result (proven). Tap a tool to see its trigger.
      </div>

      {turnBins.length > 0 && (
        <>
          <PanelTitle icon={Terminal} text="BINARIES RUN HERE" mt />
          <div style={{ fontSize: 10.5, color: C.muted, marginTop: 4, lineHeight: 1.5 }}>
            The real tools behind this turn's Bash calls — extracted from the command, not just "npx".
          </div>
          <div style={{ marginTop: 6 }}>
            {turnBins.map((b) => <BinaryRow key={b.binary} b={b} />)}
          </div>
        </>
      )}
    </div>
  );
}

export function ToolDetail({ tool, onBack }) {
  const Icon = toolIcon(tool.name);
  const ind = tool.provenance === "indirect";
  const provenFlow = ind && tool.flowValue;
  const inputStr =
    tool.input && typeof tool.input === "object"
      ? JSON.stringify(tool.input, null, 2)
      : String(tool.input ?? tool.summary ?? "");

  return (
    <div style={{ overflowY: "auto", padding: 16 }}>
      <PanelTitle icon={Icon} text="TOOL DETAIL" />
      <div style={{ fontFamily: FD, fontSize: 15, fontWeight: 600, marginTop: 8, display: "flex", alignItems: "center", gap: 8 }}>
        {tool.mcp ? `${tool.mcp.server}:${tool.mcp.tool}` : tool.name}
        {tool.errored && (
          <span style={{ fontFamily: FM, fontSize: 9, color: C.red, border: `1px solid ${C.red}`, borderRadius: 4, padding: "1px 6px", display: "inline-flex", alignItems: "center", gap: 4 }}>
            <AlertTriangle size={10} /> ERRORED
          </span>
        )}
      </div>

      {tool.mcp && (
        <div style={{ fontFamily: FM, fontSize: 9.5, color: C.cyan, marginTop: 6 }}>MCP · {tool.mcp.server}</div>
      )}

      {/* full input */}
      <div style={{ fontFamily: FM, fontSize: 9.5, color: C.muted, marginTop: 12, marginBottom: 4 }}>FULL INPUT</div>
      <pre style={{ fontFamily: FM, fontSize: 11, color: C.text2, margin: 0, background: C.black, padding: 10, borderRadius: 7, border: `1px solid ${C.borderSoft}`, whiteSpace: "pre-wrap", wordBreak: "break-word", maxHeight: 220, overflow: "auto", lineHeight: 1.5 }}>
        {inputStr}
      </pre>

      {/* provenance verdict — proven vs hypothesis separated */}
      <div style={{ marginTop: 14 }}>
        {provenFlow ? (
          <div style={{ background: C.orangeMut, border: `1px solid ${C.orangeBd}`, borderRadius: 8, padding: 12 }}>
            <div style={{ color: C.orange, fontWeight: 600, fontSize: 13, display: "flex", alignItems: "center", gap: 7 }}>
              <CornerDownRight size={15} /> Indirect — proven value-flow
            </div>
            <div style={{ fontSize: 12.5, color: C.text2, marginTop: 8, lineHeight: 1.55 }}>
              Fired because a value from an earlier <b style={{ color: C.orange }}>{tool.sourceTool}</b> result reappeared <b>verbatim</b> in this input. This is asserted, not inferred.
            </div>
            <div style={{ marginTop: 10 }}>
              <div style={{ fontFamily: FM, fontSize: 9.5, color: C.muted, marginBottom: 4 }}>VALUE THAT FLOWED</div>
              <div style={{ fontFamily: FM, fontSize: 11, color: C.orange, background: C.black, padding: "6px 9px", borderRadius: 5, border: `1px solid ${C.orangeBd}`, wordBreak: "break-all" }}>
                {tool.flowValue}
              </div>
            </div>
          </div>
        ) : ind ? (
          <div style={{ background: C.card, border: `1px dashed ${C.border}`, borderRadius: 8, padding: 12 }}>
            <div style={{ color: C.amber, fontWeight: 600, fontSize: 13 }}>Indirect — proximity (hypothesis)</div>
            <div style={{ fontSize: 12.5, color: C.text2, marginTop: 8, lineHeight: 1.55 }}>
              Likely driven by an earlier <b>{tool.sourceTool || "tool"}</b> result, but no verbatim value was pinned. A hypothesis for you to judge — not asserted.
            </div>
          </div>
        ) : (
          <div style={{ background: C.card, border: `1px solid ${C.border}`, borderRadius: 8, padding: 12 }}>
            <div style={{ color: C.text, fontWeight: 600, fontSize: 13 }}>Direct — from your instruction</div>
            <div style={{ fontSize: 12.5, color: C.text2, marginTop: 8, lineHeight: 1.55 }}>
              No earlier tool result fed this input. It traces to your query.
            </div>
          </div>
        )}
      </div>

      <div onClick={onBack} style={{ marginTop: 14, fontFamily: FM, fontSize: 11, color: C.muted, cursor: "pointer" }}>← back</div>
    </div>
  );
}

function CausalitySplit({ direct, indirect }) {
  const tot = Math.max(1, direct + indirect);
  return (
    <div style={{ display: "flex", height: 26, borderRadius: 7, overflow: "hidden", border: `1px solid ${C.borderSoft}`, marginTop: 8 }}>
      <div style={{ width: `${(100 * direct) / tot}%`, background: C.border, display: "flex", alignItems: "center", justifyContent: "center" }}>
        {direct > 0 && <span style={{ fontFamily: FM, fontSize: 10, color: C.text }}>{direct} direct</span>}
      </div>
      <div style={{ width: `${(100 * indirect) / tot}%`, background: `linear-gradient(90deg,${C.orange},${C.orangeHi})`, display: "flex", alignItems: "center", justifyContent: "center" }}>
        {indirect > 0 && <span style={{ fontFamily: FM, fontSize: 10, color: "#fff" }}>{indirect} indirect</span>}
      </div>
    </div>
  );
}
