/* mock-data.jsx → real-data adapters (Card 12)
 *
 * The design prototype shipped static RELAY_RUN / BASELINE_RUN here and the
 * comparison view read them from globals. In the 1:1 replacement the data is
 * REAL: app.js (window.byokicuBridge) maps live eval-target runs into the
 * same shapes and app.jsx feeds them to ComparePane via runState. This file
 * keeps the canonical case list + the comparison/verdict/notable LOGIC
 * (unchanged visual output) but takes the relay + baseline runs as arguments
 * instead of reading mock globals.
 *
 * Run shape (produced by the bridge, mirrors the original mock):
 *   { status, target{providerId,model,apiEndpointHost,credentialOrigin,kind},
 *     cases:[{id,status,latencyMs,outputTokens,note?}],
 *     boundary{parameterBehavior,producedLegalToolCall,finishReason,responseStatus},
 *     usage{inputTokens,outputTokens,durationMs},
 *     secretHygiene{pass,detail}, unavailable? }
 */

const CASES = [
  { id: "case_1_workspace_minimal",         label: "Workspace Minimal",         short: "Workspace" },
  { id: "case_2_context_synthesis",         label: "Context Synthesis",         short: "Context" },
  { id: "case_3_provider_context_synthesis",label: "Provider Context Synthesis",short: "Provider Ctx" },
  { id: "case_4_tool_dispatch_baseline",    label: "Tool Dispatch Baseline",    short: "Tool Dispatch" },
  { id: "case_5_serial_tool_chain",         label: "Serial Tool Chain",         short: "Tool Chain" },
  { id: "case_6_tool_failure_recovery",     label: "Tool Failure Recovery",     short: "Recovery" },
  { id: "case_7_long_context_fidelity",     label: "Long Context Fidelity",     short: "Long Ctx" }
];

function findCase(run, id) {
  const cases = run && Array.isArray(run.cases) ? run.cases : [];
  return cases.find((x) => x.id === id) || { id, status: "unknown", latencyMs: 0, outputTokens: 0 };
}

/* Build a per-case comparison row with a verdict tag.
 *   good — performance close to baseline, no behavioural drift
 *   attn — flagged: notable latency drift
 *   bad  — case failed on the relay
 */
function buildCaseComparisons(relay, baseline) {
  return CASES.map((c) => {
    const r = findCase(relay, c.id);
    const b = findCase(baseline, c.id);
    const latDelta = (r.latencyMs || 0) - (b.latencyMs || 0);
    const latPct = b.latencyMs ? (latDelta / b.latencyMs) * 100 : 0;
    // Card 92-10: `tr` is the global i18n helper (window.byokicuTr, app.jsx). These build*
    // functions run during ComparePane render, so tr() picks up the active language.
    let verdict = "good";
    let note = tr("note.matchesBaseline");
    if (r.status === "failed") {
      verdict = "bad";
      note = r.note || tr("note.failedOnRelay");
    } else if (Math.abs(latPct) > 35) {
      verdict = "attn";
      note = tr("note.latencyDrift", { sign: latPct > 0 ? "+" : "", pct: latPct.toFixed(0) });
    } else if (Math.abs(latPct) > 15) {
      verdict = "attn";
      note = tr("note.latencyDrift", { sign: latPct > 0 ? "+" : "", pct: latPct.toFixed(0) });
    }
    return { ...c, relay: r, baseline: b, latDelta, latPct, verdict, note };
  });
}

/* Pull out noteworthy items for the "worth your attention" cards. */
function buildNotables(comparisons, relay, baseline) {
  const cards = [];
  const baselineUnavailable = !baseline || baseline.unavailable || baseline.status === "unavailable";

  // Parameter handling at the API boundary.
  const paramBehavior = (relay && relay.boundary && relay.boundary.parameterBehavior) || "";
  if (paramBehavior && /^strip/i.test(paramBehavior)) {
    cards.push({
      severity: "warn",
      label: tr("nb.param.label"),
      title: tr("nb.param.title"),
      body: (
        <p>{tr("nb.param.pre")}<code>{paramBehavior}</code>{tr("nb.param.post")}</p>
      )
    });
  }

  // Failed cases.
  const failed = comparisons.filter((c) => c.verdict === "bad");
  for (const f of failed) {
    cards.push({
      severity: "bad",
      label: tr("case." + f.id + ".label"),
      title: tr("nb.fail.title"),
      body: baselineUnavailable ? (
        <p>{tr("nb.fail.nb.pre")}<code>{f.note}</code>{tr("nb.fail.nb.post")}</p>
      ) : (
        <p>{tr("nb.fail.b.pre")}<code>{Math.round(f.baseline.latencyMs)}ms</code>{tr("nb.fail.b.mid")}<code>{f.note}</code>{tr("nb.fail.b.post")}</p>
      )
    });
  }

  // Largest positive latency drift.
  const slowest = comparisons
    .filter((c) => c.verdict === "attn" && c.latPct > 0)
    .sort((a, b) => b.latPct - a.latPct)[0];
  if (slowest && !baselineUnavailable) {
    const slowestShort = tr("case." + slowest.id + ".short");
    cards.push({
      severity: "warn",
      label: tr("nb.tp.label"),
      title: tr("nb.tp.title", { pct: slowest.latPct.toFixed(0), short: slowestShort }),
      body: (
        <p>{tr("nb.tp.pre")}<code>{Math.round(slowest.latDelta)}ms</code>{tr("nb.tp.mid")}<code>{slowestShort}</code>{tr("nb.tp.post")}</p>
      )
    });
  }

  // Secret hygiene — driven by the real run-JSON scan in the bridge.
  const hygiene = (relay && relay.secretHygiene) || { pass: true, detail: "" };
  cards.push({
    severity: hygiene.pass ? "good" : "bad",
    label: tr("nb.sh.label"),
    title: hygiene.pass ? tr("nb.sh.title.ok") : tr("nb.sh.title.bad"),
    body: (
      <p>{hygiene.detail || tr("nb.sh.scanned")}{hygiene.pass ? tr("nb.sh.tail.ok") : tr("nb.sh.tail.bad")}</p>
    )
  });

  // byok.icu: did the relay's model output try to ELICIT the user's API key / credentials?
  const elicit = (relay && relay.keyElicitation) || { detected: false, detail: "" };
  cards.push({
    severity: elicit.detected ? "bad" : "good",
    label: tr("nb.elicit.label"),
    title: elicit.detected ? tr("nb.elicit.title.bad") : tr("nb.elicit.title.ok"),
    body: elicit.detected ? (
      <p>{tr("nb.elicit.body.bad.pre")}<code>{elicit.detail}</code>{tr("nb.elicit.body.bad.post")}</p>
    ) : (
      <p>{tr("nb.elicit.body.ok")}</p>
    )
  });

  if (baselineUnavailable) {
    cards.push({
      severity: "warn",
      label: tr("nb.base.label"),
      title: tr("nb.base.title"),
      body: (
        <p>{tr("nb.base.body")}</p>
      )
    });
  }

  return cards;
}

function getOverallVerdict(comparisons) {
  const anyFail = comparisons.some((c) => c.verdict === "bad");
  const anyAttn = comparisons.some((c) => c.verdict === "attn");
  if (anyFail) return { key: "warn", stamp: "ATTENTION", headline: "Relay is mostly trustworthy — but read the flags." };
  if (anyAttn) return { key: "warn", stamp: "ATTENTION", headline: "Relay is mostly trustworthy — but read the flags." };
  return { key: "ok", stamp: "TRUSTED", headline: "Relay behaviour matches the canonical baseline." };
}

Object.assign(window, {
  CASES,
  buildCaseComparisons,
  buildNotables,
  getOverallVerdict
});
