/* ============================================================
   AFTERWAVE — RUN  (window.RUN)
   New Simulation (submit per §2: artifact, platforms[], persona_set?,
   lens?) + Running (live stage stream §3: parsing→encoding→
   simulating→aggregating) with typed error + retry.
   ============================================================ */
(function () {
  "use strict";
  const { useState, useEffect, useRef } = React;
  const API = window.API, UI = window.UIX, VZ = window.VZ;
  const h = React.createElement;

  function NewSimulation({ onRun, onCancel }) {
    const [type, setType] = useState("video");
    const [lens, setLens] = useState("social_media");
    const [caption, setCaption] = useState("Your private shoreline awaits this winter.");
    const [plats, setPlats] = useState({ tiktok: true, instagram: true, x: true });
    const [err, setErr] = useState(null);
    const toggle = (id) => setPlats((s) => ({ ...s, [id]: !s[id] }));
    const submit = () => {
      const chosen = Object.keys(plats).filter((p) => plats[p]);
      if (type === "text" && !caption.trim()) return setErr("Add caption text, or attach media before running.");
      if (!chosen.length) return setErr("Select at least one platform.");
      setErr(null); onRun({ artifact: { type, caption, lang: "en" }, platforms: chosen, lens });
    };
    return h("div", { className: "wrap", style: { maxWidth: 860 } },
      h("div", { className: "phead" }, h("div", null, h("div", { className: "eyebrow" }, "new prediction"), h("h1", { style: { fontFamily: "var(--sans)", fontWeight: 600, fontSize: 27 } }, "Submit an artifact"),
        h("div", { className: "sub" }, "Predict the audience reaction before you publish."))),
      err ? h("div", { className: "notice", "data-kind": "error", style: { marginBottom: 18 } }, h("span", { className: "g", style: { width: 9, height: 9, borderRadius: "50%", background: "var(--neg)" } }), err) : null,
      h("div", { className: "grid g2", style: { alignItems: "start", marginBottom: 16 } },
        h("div", { className: "card card-pad" },
          h("div", { className: "eyebrow", style: { marginBottom: 12 } }, "artifact"),
          h("div", { style: { display: "flex", gap: 6, marginBottom: 14, flexWrap: "wrap" } }, ["video", "image", "text", "audio"].map((t) => h("button", { key: t, className: "chip", "data-on": type === t, onClick: () => setType(t), style: { textTransform: "capitalize" } }, t))),
          h("div", { style: { aspectRatio: "16/9", border: "1px dashed var(--line-3)", borderRadius: "var(--r-sm)", display: "grid", placeItems: "center", textAlign: "center", color: "var(--ink-3)", padding: 16, background: "var(--surface-2)", marginBottom: 14 } },
            type === "text" ? h("span", { style: { fontSize: 12.5 } }, "text-only — no media") : h("div", null, h(UI.Icon, { name: UI.TYPE_ICON[cap(type)], size: 26 }), h("div", { style: { fontSize: 12.5, marginTop: 8 } }, "Drag & drop or browse"))),
          h("div", { className: "field", style: { margin: 0 } }, h("label", null, "caption / copy"), h("textarea", { className: "input", rows: 3, value: caption, onChange: (e) => setCaption(e.target.value) }))),
        h("div", { className: "card card-pad" },
          h("div", { className: "eyebrow", style: { marginBottom: 12 } }, "configuration"),
          h("div", { className: "field" }, h("label", null, "lens"),
            h("div", { style: { display: "flex", gap: 8 } }, [["social_media", "Social media"], ["advertising", "Advertising"]].map(([v, l]) => h("button", { key: v, className: "chip", "data-on": lens === v, onClick: () => setLens(v), style: { flex: 1, justifyContent: "center" } }, l)))),
          h("div", { className: "field", style: { margin: 0 } }, h("label", null, "platforms"),
            h("div", { style: { display: "grid", gap: 8 } }, API.PLATFORMS.map((p) => h("button", { key: p.id, className: "chip", "data-on": plats[p.id], onClick: () => toggle(p.id), style: { justifyContent: "space-between", padding: "9px 12px" } }, p.label, h("span", { className: "dim-2" }, plats[p.id] ? "included" : "off"))))),
          h("div", { style: { marginTop: 16, paddingTop: 14, borderTop: "1px solid var(--line)", fontSize: 12.5, color: "var(--ink-2)" } }, "Runs the 12-persona swarm · target < 30s"))),
      h("div", { style: { display: "flex", gap: 10, justifyContent: "flex-end" } },
        h("button", { className: "btn ghost", onClick: onCancel }, "Cancel"),
        h("button", { className: "btn", onClick: submit }, h(UI.Icon, { name: "play", size: 13 }), "Run prediction")));
  }
  const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);

  function Running({ runId, failMode, onComplete, onCancel }) {
    const [active, setActive] = useState(null);
    const [done, setDone] = useState({});
    const [error, setError] = useState(null);
    const [pct, setPct] = useState(0);
    const stop = useRef(null);
    const start = () => {
      setActive(null); setDone({}); setError(null); setPct(0);
      let i = 0;
      stop.current = API.stream((ev) => {
        if (ev.event === "stage" && ev.status === "started") { setActive(ev.stage); setPct(i / API.STAGES.length); }
        else if (ev.event === "stage" && ev.status === "done") { i++; setDone((d) => ({ ...d, [ev.stage]: true })); setPct(i / API.STAGES.length); }
        else if (ev.event === "complete") { setPct(1); setTimeout(onComplete, 450); }
        else if (ev.event === "error") setError(ev);
      }, { failAt: failMode ? "encoding" : null, runId });
    };
    useEffect(() => { start(); return () => stop.current && stop.current(); }, []);
    const idx = API.STAGES.findIndex((s) => s.stage === active);

    return h("div", { className: "wrap", style: { maxWidth: 720 } },
      h("button", { className: "btn ghost sm", onClick: onCancel, style: { marginBottom: 16 } }, "← Back"),
      h("div", { className: "phead" }, h("div", null, h("div", { className: "eyebrow" }, "live · " + runId),
        h("h1", { style: { fontFamily: "var(--sans)", fontWeight: 600, fontSize: 24 } }, "Running prediction"),
        h("div", { className: "sub" }, "Streaming over WebSocket · stages map to layers L1→L4"))),
      h("div", { className: "card card-pad", style: { display: "flex", alignItems: "center", gap: 24, marginBottom: 16 } },
        h(VZ.Ring, { pct, size: 132, sub: error ? "stopped" : "processing" }),
        error ? h("div", null, h("div", { style: { fontWeight: 600, fontSize: 16, color: "var(--neg-ink)" } }, "Run failed"), h("p", { className: "dim", style: { margin: "6px 0 0", fontSize: 13 } }, error.message))
          : h("div", null, h("div", { style: { fontWeight: 600, fontSize: 17 } }, active ? (API.STAGES.find((s) => s.stage === active) || {}).label : "Finishing"),
            h("p", { className: "dim", style: { margin: "6px 0 0", fontSize: 13.5 } }, active ? (API.STAGES.find((s) => s.stage === active) || {}).desc : "Assembling the report"))),
      h("div", { className: "card" },
        API.STAGES.map((s, i) => {
          const st = done[s.stage] ? "done" : active === s.stage ? "active" : (error && i < API.STAGES.findIndex((z) => z.stage === error.stage)) ? "done" : "wait";
          const isErr = error && error.stage === s.stage;
          return h("div", { key: s.stage, className: "phase", "data-st": isErr ? "wait" : st, style: isErr ? { borderColor: "var(--neg)" } : null },
            h("span", { className: "pn" }, st === "done" ? h(UI.Icon, { name: "check", size: 12 }) : isErr ? "!" : st === "wait" ? (i + 1) : ""),
            h("div", { style: { flex: 1 } }, h("div", { className: "pt" }, s.label, h("span", { className: "eyebrow", style: { marginInlineStart: 8, fontSize: 8.5 } }, s.layer)), h("div", { className: "pd" }, s.desc)));
        }),
        error ? h("div", { style: { padding: "14px 18px", borderTop: "1px solid var(--line)", display: "flex", gap: 8 } },
          h("button", { className: "btn sm", onClick: start }, "Retry"), h("button", { className: "btn ghost sm", onClick: onCancel }, "Back")) : null));
  }

  window.RUN = { NewSimulation, Running };
})();
