/* deck-present.jsx — shared HTML presentation display + per-slide enhancement
   rendering + interactive game gate. Loaded in BOTH the Educator dashboard
   (Studio preview + Study Builder) and the Learner LMS (deck viewer), so a
   slide always looks identical wherever it is shown.

   Enhancement data lives on  deck.enhance = { [slideIndex]: SlideEnh }
   SlideEnh = {
     accent : "#hex",                 // accent colour for frame / title
     title  : "Overlay title",        // optional caption pill (top-left)
     caption: "Lower-third caption",  // optional caption bar (bottom)
     frame  : true,                   // accent focus ring
     game   : {
       type   : "quiz" | "poll" | "reflect",
       q      : "Question text",
       options: ["A","B","C","D"],    // quiz / poll
       answer : 1,                    // quiz correct index
       xp     : 50
     }
   } */

const DECK_ACCENTS = ["#f99d25", "#1281c4", "#3bc1ce", "#26890c", "#e21b3c", "#7c3aed"];

/* Renders an AI-rebuilt HTML slide in a scaled, aspect-locked iframe.
   The iframe is keyed to a hash of its content so it reliably reloads when
   the HTML is regenerated (browsers don't always re-parse srcdoc in place). */
function DeckHtmlSlide({ html, ratio, maxW = "90vw", maxH = "calc(100vh - 150px)", radius = 6 }) {
  const r = ratio || 16 / 9;
  const key = React.useMemo(() => {
    let h = 0;for (let i = 0; i < html.length; i++) h = h * 31 + html.charCodeAt(i) | 0;
    return h + ":" + html.length;
  }, [html]);
  return (
    <div style={{ width: `min(${maxW}, calc(${maxH} * ${r}))`, maxWidth: "100%", aspectRatio: String(r), borderRadius: radius, overflow: "hidden", background: "#fff", boxShadow: "0 20px 60px rgba(0,0,0,.5)" }}>
      <iframe key={key} srcDoc={html} title="HTML slide" sandbox="allow-scripts" style={{ width: "100%", height: "100%", border: "none", display: "block" }} />
    </div>);

}

/* Style overlays drawn on top of a slide image (title pill / caption / frame). */
function DeckEnhanceLayer({ enh }) {
  if (!enh) return null;
  const accent = enh.accent || "#f99d25";
  return (
    <div style={{ position: "absolute", inset: 0, pointerEvents: "none", zIndex: 4 }}>
      {enh.frame && <div style={{ position: "absolute", inset: 0, border: "4px solid " + accent, borderRadius: 6, boxShadow: "inset 0 0 30px " + accent + "22" }} />}
      {enh.title &&
      <div style={{ position: "absolute", top: 18, left: 18, display: "inline-flex", alignItems: "center", gap: 8, background: accent, color: "#10203c", fontFamily: "var(--display)", fontWeight: 800, fontSize: 18, padding: "8px 16px", borderRadius: 10, boxShadow: "0 6px 20px rgba(0,0,0,.3)" }}>{enh.title}</div>
      }
      {enh.caption &&
      <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, background: "linear-gradient(transparent, rgba(7,14,26,.86))", padding: "44px 28px 20px", color: "#fff", fontSize: 19, fontWeight: 600, lineHeight: 1.45 }}>
          <span style={{ borderLeft: "4px solid " + accent, paddingLeft: 14, display: "inline-block" }}>{enh.caption}</span>
        </div>
      }
    </div>);

}

/* Interactive game card. Controlled-ish: calls onAward(xp) once when the
   learner completes it. `live` enables answering; in static builder preview
   pass live={false} to just show the layout. */
function DeckGameGate({ game, onAward, live = true }) {
  const [picked, setPicked] = React.useState(null);
  const [text, setText] = React.useState("");
  const [done, setDone] = React.useState(false);
  const [awardedAmt, setAwardedAmt] = React.useState(null);
  const [timeLeft, setTimeLeft] = React.useState(game && game.time || 20);
  const [cAns, setCAns] = React.useState("");
  const [cFeedback, setCFeedback] = React.useState("");
  const [cBusy, setCBusy] = React.useState(false);
  const isKahoot = game && game.type === "kahoot";
  React.useEffect(() => {
    if (!isKahoot || !live || picked !== null) return;
    if (timeLeft <= 0) {setPicked(-1);return;}
    const t = setTimeout(() => setTimeLeft(timeLeft - 1), 1000);
    return () => clearTimeout(t);
  }, [isKahoot, live, picked, timeLeft]);

  if (!game) return null;
  const accent = "#f99d25";
  const maxTime = game.time || 20;

  function award(amt) {if (!done) {const a = amt != null ? amt : game.xp || 20;setDone(true);setAwardedAmt(a);onAward && onAward(a);}}
  function pick(i) {
    if (!live || picked !== null) return;
    setPicked(i);
    if (game.type === "quiz") {if (i === game.answer) award();} else
    if (isKahoot) {if (i === game.answer) award(Math.max(10, Math.round((game.xp || 100) * timeLeft / maxTime)));} else
    award(); // poll: any answer awards
  }
  async function submitClaude() {
    if (!live || done || !cAns.trim() || cBusy) return;
    if (!window.claude || !window.claude.complete) {setCFeedback("Saved — AI feedback runs in the live environment.");award();return;}
    setCBusy(true);
    try {
      const out = await window.claude.complete([
      'You are a friendly, encouraging training tutor. The learner was asked: "' + (game.q || "") + '".',
      'Their answer: "' + cAns.trim() + '".',
      "Give brief feedback (max 3 sentences): acknowledge what's good and add one concrete tip to improve. Plain, supportive language."].
      join("\n"));
      setCFeedback((out || "").trim() || "Thanks for your answer!");
    } catch (e) {setCFeedback("Thanks for your answer!");}
    award();
    setCBusy(false);
  }

  const wrap = { background: "rgba(13,25,41,.97)", border: "1px solid rgba(249,157,37,.35)", borderRadius: 16, padding: "20px 22px", boxShadow: "0 18px 50px rgba(0,0,0,.5)", maxWidth: 620, width: "100%" };
  const head =
  <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 12 }}>
      <span style={{ display: "inline-flex", alignItems: "center", gap: 5, background: "rgba(249,157,37,.18)", color: accent, fontSize: 11.5, fontWeight: 800, letterSpacing: ".08em", textTransform: "uppercase", padding: "4px 11px", borderRadius: 999 }}><Icon name="bolt" size={12} />{{ quiz: "Quiz", poll: "Live Poll", reflect: "Reflection", kahoot: "Kahoot!", claude: "Ask Claude" }[game.type] || "Quiz"}</span>
      <span style={{ marginLeft: "auto", fontFamily: "var(--display)", fontWeight: 800, fontSize: 14, color: accent }}>+{game.xp || 20} XP</span>
    </div>;


  return (
    <div style={wrap}>
      {head}
      <div style={{ fontFamily: "var(--display)", fontWeight: 800, fontSize: 21, color: "#fff", lineHeight: 1.25, marginBottom: 16 }}>{game.q || "Untitled question"}</div>

      {(game.type === "quiz" || game.type === "poll") &&
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
          {(game.options || []).filter((o) => o !== "" && o != null).map((opt, i) => {
          let bg = "rgba(255,255,255,.06)",bd = "rgba(255,255,255,.14)",col = "#dce8f7";
          if (picked !== null) {
            if (game.type === "quiz") {
              if (i === game.answer) {bg = "rgba(38,137,12,.25)";bd = "#26890c";col = "#86e29a";} else
              if (i === picked) {bg = "rgba(226,27,60,.22)";bd = "#e21b3c";col = "#f5a3b1";} else
              {col = "#6b88b0";}
            } else if (i === picked) {bg = "rgba(18,129,196,.25)";bd = "#1281c4";col = "#8fd0f5";}
          }
          return (
            <button key={i} onClick={() => pick(i)} disabled={!live || picked !== null}
            style={{ display: "flex", alignItems: "center", gap: 11, padding: "13px 15px", borderRadius: 11, border: "1.5px solid " + bd, background: bg, color: col, fontFamily: "var(--body)", fontSize: 15.5, fontWeight: 600, textAlign: "left", cursor: live && picked === null ? "pointer" : "default", transition: "all .15s" }}>
                <span style={{ width: 26, height: 26, borderRadius: 7, background: "rgba(255,255,255,.1)", display: "grid", placeItems: "center", fontFamily: "var(--display)", fontWeight: 800, fontSize: 13, flexShrink: 0 }}>{String.fromCharCode(65 + i)}</span>
                {opt}
              </button>);

        })}
        </div>
      }

      {game.type === "reflect" &&
      <div>
          <textarea value={text} onChange={(e) => setText(e.target.value)} disabled={!live || done} placeholder="Type your reflection…"
        style={{ width: "100%", minHeight: 80, resize: "none", background: "rgba(255,255,255,.06)", border: "1.5px solid rgba(255,255,255,.14)", borderRadius: 11, color: "#dce8f7", fontSize: 15, padding: 13, outline: "none", fontFamily: "var(--body)", lineHeight: 1.5 }} />
          <button onClick={() => text.trim() && award()} disabled={!live || done || !text.trim()}
        style={{ marginTop: 10, padding: "10px 20px", borderRadius: 10, border: "none", background: done ? "rgba(255,255,255,.12)" : accent, color: done ? "#8aa" : "#10203c", fontFamily: "var(--display)", fontWeight: 800, fontSize: 14, cursor: done || !text.trim() ? "default" : "pointer" }}>{done ? "Submitted ✓" : "Submit reflection"}</button>
        </div>
      }

      {game.type === "kahoot" &&
      <div>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
            <div style={{ flex: 1, height: 9, borderRadius: 999, background: "rgba(255,255,255,.1)", overflow: "hidden" }}>
              <div style={{ height: "100%", width: (picked === null ? timeLeft / maxTime * 100 : 0) + "%", background: timeLeft / maxTime > 0.35 ? "linear-gradient(90deg,#f99d25,#3bc1ce)" : "#e21b3c", transition: "width 1s linear", borderRadius: 999 }} />
            </div>
            <span style={{ fontFamily: "var(--display)", fontWeight: 800, fontSize: 17, color: picked === null ? "#fff" : "#6b88b0", minWidth: 30, textAlign: "right" }}>{picked === null ? timeLeft : "⏱"}</span>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
            {(game.options || []).filter((o) => o !== "" && o != null).map((opt, i) => {
            const KC = ["#e21b3c", "#1368ce", "#26890c", "#d89e00"],KS = ["▲", "◆", "●", "■"];
            const dim = picked !== null && i !== game.answer && i !== picked;
            const showCorrect = picked !== null && i === game.answer;
            return (
              <button key={i} onClick={() => pick(i)} disabled={!live || picked !== null}
              style={{ display: "flex", alignItems: "center", gap: 11, padding: "15px 16px", borderRadius: 12, border: "none", background: KC[i % 4], color: "#fff", fontFamily: "var(--display)", fontWeight: 800, fontSize: 16, textAlign: "left", cursor: live && picked === null ? "pointer" : "default", opacity: dim ? 0.35 : 1, outline: showCorrect ? "4px solid #fff" : "none", outlineOffset: "-2px", minHeight: 60, transition: "all .15s" }}>
                  <span style={{ fontSize: 22, flexShrink: 0 }}>{KS[i % 4]}</span>{opt}
                </button>);

          })}
          </div>
          {picked !== null &&
        <div style={{ marginTop: 12, fontSize: 14, fontWeight: 700, color: picked === game.answer ? "#86e29a" : "#f5a3b1" }}>{picked === game.answer ? "Correct! ⚡ Speed bonus applied" : picked === -1 ? "Time's up!" : "Not quite — correct answer highlighted"}</div>}
        </div>
      }

      {game.type === "claude" &&
      <div>
          <textarea value={cAns} onChange={(e) => setCAns(e.target.value)} disabled={!live || done} placeholder="Type your answer for the AI tutor…"
        style={{ width: "100%", minHeight: 72, resize: "none", background: "rgba(255,255,255,.06)", border: "1.5px solid rgba(255,255,255,.14)", borderRadius: 11, color: "#dce8f7", fontSize: 15, padding: 13, outline: "none", fontFamily: "var(--body)", lineHeight: 1.5 }} />
          <button onClick={submitClaude} disabled={!live || done || !cAns.trim() || cBusy}
        style={{ marginTop: 10, padding: "10px 20px", borderRadius: 10, border: "none", background: done || !cAns.trim() ? "rgba(255,255,255,.12)" : accent, color: done || !cAns.trim() ? "#8aa" : "#10203c", fontFamily: "var(--display)", fontWeight: 800, fontSize: 14, cursor: done || !cAns.trim() || cBusy ? "default" : "pointer", display: "inline-flex", alignItems: "center", gap: 8 }}>{cBusy ? "✨ Checking…" : done ? "Submitted ✓" : "✨ Ask Claude to check"}</button>
          {cFeedback &&
        <div style={{ marginTop: 12, background: "rgba(59,193,206,.1)", border: "1px solid rgba(59,193,206,.25)", borderRadius: 11, padding: "12px 14px", fontSize: 14, color: "#cfeef2", lineHeight: 1.55 }}>
              <div style={{ fontSize: 11, fontWeight: 800, letterSpacing: ".08em", textTransform: "uppercase", color: "#3bc1ce", marginBottom: 6 }}>✨ AI tutor feedback</div>{cFeedback}
            </div>}
        </div>
      }

      {done && <div style={{ marginTop: 13, display: "flex", alignItems: "center", gap: 7, color: "#86e29a", fontSize: 14, fontWeight: 700 }}><Icon name="check" size={15} />Nice — {awardedAmt != null ? awardedAmt : game.xp || 20} XP earned</div>}
    </div>);

}

/* Full HTML presentation display (portal). Used for Studio preview and the
   Study-Builder "preview as learner". */
function DeckPresent({ deck, enhance, onClose, startIdx }) {
  const slides = deck.slides || [];
  const enh = enhance || deck.enhance || {};
  const TOTAL = slides.length;
  const [idx, setIdx] = React.useState(startIdx || 0);
  const [xp, setXp] = React.useState(0);
  const [awarded, setAwarded] = React.useState({});
  const ratio = deck.ratio || 16 / 9;

  function go(n) {setIdx(Math.max(0, Math.min(TOTAL - 1, n)));}
  React.useEffect(() => {
    function k(e) {if (e.key === "ArrowRight") go(idx + 1);else if (e.key === "ArrowLeft") go(idx - 1);else if (e.key === "Escape") onClose();}
    window.addEventListener("keydown", k);return () => window.removeEventListener("keydown", k);
  }, [idx]);

  const cur = enh[idx] || enh[String(idx)];
  function award(amount) {if (awarded[idx]) return;setAwarded((a) => ({ ...a, [idx]: true }));setXp((x) => x + amount);}
  const anyGame = Object.keys(enh).some((k) => (enh[k] || {}).game);

  return ReactDOM.createPortal(
    <div style={{ position: "fixed", inset: 0, zIndex: 1260, background: "#06101e", display: "flex", flexDirection: "column", fontFamily: "var(--body)" }}>
      {/* top bar */}
      <div style={{ height: 54, flex: "none", display: "flex", alignItems: "center", gap: 14, padding: "0 20px", borderBottom: "1px solid #14233c" }}>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 7, fontSize: 11.5, fontWeight: 700, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--vh-orange,#f99d25)" }}><Icon name="search" size={14} />HTML preview</span>
        <span style={{ fontSize: 15, fontWeight: 600, color: "#adc5e8", flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{deck.title}</span>
        {anyGame && <span style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "rgba(249,157,37,.16)", border: "1px solid rgba(249,157,37,.3)", borderRadius: 999, padding: "5px 13px", fontFamily: "var(--display)", fontWeight: 800, fontSize: 14, color: "#f99d25" }}><Icon name="bolt" size={14} />{xp} XP</span>}
        <span style={{ fontSize: 13, fontWeight: 600, color: "#6b88b0" }}>Slide {idx + 1} / {TOTAL}</span>
        <button onClick={onClose} style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 13, padding: "7px 13px", borderRadius: 8, background: "rgba(255,255,255,.1)", color: "#fff", border: "none", cursor: "pointer", fontFamily: "var(--body)", fontWeight: 600 }}><Icon name="x" size={15} />Close</button>
      </div>

      {/* stage */}
      <div style={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 16, padding: "20px 16px", minHeight: 0, position: "relative" }}>
        <button onClick={() => go(idx - 1)} disabled={idx === 0} style={{ flex: "none", width: 50, height: 50, borderRadius: "50%", border: "none", background: "rgba(255,255,255,.1)", color: "#fff", cursor: idx === 0 ? "default" : "pointer", opacity: idx === 0 ? .3 : 1, display: "grid", placeItems: "center" }}><Icon name="chevL" size={23} /></button>

        <div style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center", gap: 18, maxWidth: "calc(100% - 150px)", maxHeight: "100%" }}>
          <div style={{ position: "relative", display: "inline-block", lineHeight: 0 }}>
            {cur && cur.html ?
            <DeckHtmlSlide html={cur.html} ratio={ratio} maxH={cur && cur.game ? "calc(100vh - 380px)" : "calc(100vh - 150px)"} /> :
            <img src={slides[idx]} alt={"Slide " + (idx + 1)} style={{ maxWidth: "100%", maxHeight: cur && cur.game ? "calc(100vh - 380px)" : "calc(100vh - 150px)", objectFit: "contain", borderRadius: 6, boxShadow: "0 24px 70px rgba(0,0,0,.6)", display: "block" }} />}
            <DeckEnhanceLayer enh={cur} />
          </div>
          {cur && cur.game && <DeckGameGate game={cur.game} onAward={award} live={true} />}
        </div>

        <button onClick={() => go(idx + 1)} disabled={idx === TOTAL - 1} style={{ flex: "none", width: 50, height: 50, borderRadius: "50%", border: "none", background: "rgba(255,255,255,.1)", color: "#fff", cursor: idx === TOTAL - 1 ? "default" : "pointer", opacity: idx === TOTAL - 1 ? .3 : 1, display: "grid", placeItems: "center", transform: "scaleX(-1)" }}><Icon name="chevL" size={23} /></button>
      </div>

      {/* thumbnail strip */}
      <div style={{ flex: "none", height: 74, display: "flex", gap: 8, padding: "0 20px 14px", overflowX: "auto", justifyContent: TOTAL < 14 ? "center" : "flex-start" }} className="scroll">
        {slides.map((img, i) => {
          const e = enh[i] || enh[String(i)];
          return (
            <div key={i} style={{ position: "relative", flex: "none" }}>
              <img src={img} alt="" onClick={() => go(i)} style={{ height: 56, aspectRatio: String(ratio), objectFit: "cover", borderRadius: 5, cursor: "pointer", border: i === idx ? "2.5px solid var(--vh-orange,#f99d25)" : "2.5px solid transparent", opacity: i === idx ? 1 : .5, transition: "all .15s" }} />
              {e && e.game && <span style={{ position: "absolute", top: 2, right: 4, width: 16, height: 16, borderRadius: "50%", background: "#f99d25", color: "#10203c", display: "grid", placeItems: "center", fontSize: 9, fontWeight: 800 }}>⚡</span>}
            </div>);

        })}
      </div>
    </div>, document.body);
}

Object.assign(window, { DECK_ACCENTS, DeckHtmlSlide, DeckEnhanceLayer, DeckGameGate, DeckPresent });