/* ============================================================
   MTOPS Academy — shared components
   ============================================================ */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

const cls = (...a) => a.filter(Boolean).join(" ");

/* ---- localStorage hook (namespaced) ---- */
const LS = "mtops-academy-v1";
function loadStore() {
  try { return JSON.parse(localStorage.getItem(LS)) || {}; } catch (e) { return {}; }
}
function useStore(key, initial) {
  const [val, setVal] = useState(() => {
    const s = loadStore();
    return key in s ? s[key] : initial;
  });
  const set = useCallback((next) => {
    setVal((prev) => {
      const resolved = typeof next === "function" ? next(prev) : next;
      const s = loadStore(); s[key] = resolved;
      try { localStorage.setItem(LS, JSON.stringify(s)); } catch (e) {}
      return resolved;
    });
  }, [key]);
  return [val, set];
}

/* ---- geometric markers per group kind ---- */
function Marker({ kind, size = 16 }) {
  const s = size, c = s / 2;
  const stroke = "currentColor";
  let inner;
  if (kind === "mind") {
    inner = <g><circle cx={c} cy={c} r={c - 2} fill="none" stroke={stroke} strokeWidth="1.4" /><circle cx={c} cy={c} r="2.1" fill={stroke} /></g>;
  } else if (kind === "warn") {
    inner = <path d={`M${c} 2 L${s - 2} ${s - 2.5} L2 ${s - 2.5} Z`} fill="none" stroke={stroke} strokeWidth="1.4" strokeLinejoin="round" />;
  } else if (kind === "tool") {
    inner = <g><rect x="2.5" y="2.5" width={s - 5} height={s - 5} fill="none" stroke={stroke} strokeWidth="1.4" /><path d={`M2.5 ${c} H${s - 2.5} M${c} 2.5 V${s - 2.5}`} stroke={stroke} strokeWidth="1" opacity=".5" /></g>;
  } else if (kind === "diagram") {
    inner = <g fill="none" stroke={stroke} strokeWidth="1.3"><path d={`M2.5 ${s - 3} A ${s - 5} ${s - 5} 0 0 1 ${s - 3} 2.5`} /><path d={`M5.5 ${s - 3} A ${s - 8} ${s - 8} 0 0 1 ${s - 3} 5.5`} opacity=".6" /><circle cx="3" cy={s - 3} r="1.4" fill={stroke} /></g>;
  } else { /* idea */
    inner = <path d={`M${c} 2 L${s - 2} ${c} L${c} ${s - 2} L2 ${c} Z`} fill="none" stroke={stroke} strokeWidth="1.4" strokeLinejoin="round" />;
  }
  return <svg width={s} height={s} viewBox={`0 0 ${s} ${s}`} style={{ display: "block", flex: "none" }}>{inner}</svg>;
}

/* ---- progress ring ---- */
function ProgressRing({ pct, size = 44, stroke = 3.5, children }) {
  const r = (size - stroke) / 2;
  const circ = 2 * Math.PI * r;
  const off = circ * (1 - Math.max(0, Math.min(1, pct)));
  return (
    <div style={{ position: "relative", width: size, height: size, flex: "none" }}>
      <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--line-2)" strokeWidth={stroke} />
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--accent)" strokeWidth={stroke}
          strokeDasharray={circ} strokeDashoffset={off} strokeLinecap="round"
          style={{ transition: "stroke-dashoffset .5s cubic-bezier(.4,0,.2,1)", filter: pct > 0 ? "drop-shadow(0 0 4px var(--accent-glow))" : "none" }} />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
        fontFamily: "var(--mono)", fontSize: size < 40 ? 9 : 10.5, color: pct >= 1 ? "var(--accent)" : "var(--tx-3)" }}>
        {children != null ? children : `${Math.round(pct * 100)}`}
      </div>
    </div>
  );
}

/* ---- thin progress bar ---- */
function ProgressBar({ pct, height = 5 }) {
  return (
    <div style={{ background: "var(--line-2)", borderRadius: 999, height, overflow: "hidden", width: "100%" }}>
      <div style={{ width: `${Math.round(pct * 100)}%`, height: "100%", borderRadius: 999,
        background: "linear-gradient(90deg, var(--accent-deep, var(--accent)), var(--accent))",
        boxShadow: pct > 0 ? "0 0 12px var(--accent-glow)" : "none",
        transition: "width .5s cubic-bezier(.4,0,.2,1)" }} />
    </div>
  );
}

/* ---- knowledge check ---- */
function KnowledgeCheck({ quiz, moduleId }) {
  const [answers, setAnswers] = useStore(`quiz:${moduleId}`, {});
  const [revealed, setRevealed] = useState({});
  if (!quiz || !quiz.length) return null;

  const choose = (qi, oi) => {
    if (answers[qi] != null) return; // lock after answer
    setAnswers((p) => ({ ...p, [qi]: oi }));
    setRevealed((p) => ({ ...p, [qi]: true }));
  };
  const correct = quiz.filter((q, qi) => answers[qi] === q.answer).length;
  const done = quiz.every((q, qi) => answers[qi] != null);

  return (
    <section className="kcheck panel ticked" style={{ padding: "26px 26px 28px", marginTop: 30 }}>
      <header style={{ display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 12, marginBottom: 20 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <span className="pill accent" style={{ color: "var(--accent)", borderColor: "var(--accent-line)", background: "var(--accent-soft)" }}>
            <span className="dot" style={{ background: "var(--accent)", boxShadow: "0 0 8px var(--accent)" }}></span>KNOWLEDGE CHECK
          </span>
          <span className="eyebrow">{quiz.length} {quiz.length === 1 ? "question" : "questions"}</span>
        </div>
        {done && <span className="mono" style={{ fontSize: 13, color: correct === quiz.length ? "var(--mint)" : "var(--amber)" }}>{correct}/{quiz.length} correct</span>}
      </header>

      <div style={{ display: "flex", flexDirection: "column", gap: 22 }}>
        {quiz.map((q, qi) => {
          const picked = answers[qi];
          const isDone = picked != null;
          return (
            <div key={qi}>
              <div style={{ display: "flex", gap: 10, marginBottom: 12 }}>
                <span className="mono" style={{ color: "var(--accent)", fontSize: 13, flex: "none" }}>{String(qi + 1).padStart(2, "0")}</span>
                <p className="disp" style={{ margin: 0, fontSize: 16, fontWeight: 500, lineHeight: 1.35 }}>{q.q}</p>
              </div>
              <div style={{ display: "grid", gap: 8, paddingLeft: 28 }}>
                {q.options.map((opt, oi) => {
                  const isCorrect = oi === q.answer;
                  const isPicked = picked === oi;
                  let bg = "var(--bg-1)", bd = "var(--line)", col = "var(--tx-2)";
                  if (isDone && isCorrect) { bg = "var(--mint-soft)"; bd = "var(--line-mint)"; col = "var(--mint)"; }
                  else if (isDone && isPicked && !isCorrect) { bg = "var(--red-soft)"; bd = "rgba(239,90,107,.4)"; col = "var(--red)"; }
                  return (
                    <button key={oi} onClick={() => choose(qi, oi)} disabled={isDone}
                      style={{ textAlign: "left", display: "flex", alignItems: "center", gap: 11, cursor: isDone ? "default" : "pointer",
                        padding: "11px 14px", borderRadius: 8, border: `1px solid ${bd}`, background: bg, color: col,
                        font: "inherit", fontSize: 14.5, transition: "all .15s ease" }}
                      onMouseEnter={(e) => { if (!isDone) { e.currentTarget.style.borderColor = "var(--accent-line)"; e.currentTarget.style.color = "var(--tx)"; } }}
                      onMouseLeave={(e) => { if (!isDone) { e.currentTarget.style.borderColor = "var(--line)"; e.currentTarget.style.color = "var(--tx-2)"; } }}>
                      <span className="mono" style={{ fontSize: 11, opacity: .7, flex: "none" }}>{String.fromCharCode(65 + oi)}</span>
                      <span style={{ flex: 1 }}>{opt}</span>
                      {isDone && isCorrect && <span className="mono" style={{ fontSize: 11 }}>✓</span>}
                      {isDone && isPicked && !isCorrect && <span className="mono" style={{ fontSize: 11 }}>✕</span>}
                    </button>
                  );
                })}
              </div>
              {revealed[qi] && q.why && (
                <p className="fade-in" style={{ margin: "11px 0 0 28px", fontSize: 13.5, color: "var(--tx-3)", lineHeight: 1.5,
                  borderLeft: "2px solid var(--accent-line)", paddingLeft: 12 }}>{q.why}</p>
              )}
            </div>
          );
        })}
      </div>
    </section>
  );
}

/* ---- reflection exercise (fillable, persisted) ---- */
function ReflectionExercise({ reflection, moduleId }) {
  const [vals, setVals] = useStore(`reflect:${moduleId}`, {});
  const [saved, setSaved] = useState(false);
  const tRef = useRef(null);
  const onChange = (i, v) => {
    setVals((p) => ({ ...p, [i]: v }));
    setSaved(true); clearTimeout(tRef.current);
    tRef.current = setTimeout(() => setSaved(false), 1400);
  };
  const filled = reflection.questions.filter((_, i) => (vals[i] || "").trim().length > 0).length;

  return (
    <section className="panel ticked fade-in" style={{ padding: "28px 28px 30px", marginTop: 30 }}>
      <header style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 14, flexWrap: "wrap", marginBottom: 8 }}>
        <div>
          <span className="eyebrow">Interactive exercise</span>
          <h3 className="disp" style={{ margin: "8px 0 0", fontSize: 22, fontWeight: 600 }}>{reflection.title}</h3>
        </div>
        <ProgressRing pct={filled / reflection.questions.length} size={46}>{filled}/{reflection.questions.length}</ProgressRing>
      </header>
      <p style={{ color: "var(--tx-3)", fontSize: 14, maxWidth: 620, margin: "4px 0 22px" }}>{reflection.intro}</p>
      <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
        {reflection.questions.map((q, i) => (
          <div key={i}>
            <div style={{ display: "flex", gap: 10, marginBottom: 13 }}>
              <span className="mono" style={{ color: "var(--accent)", fontSize: 13, flex: "none" }}>{String(i + 1).padStart(2, "0")}</span>
              <span style={{ fontSize: 15, lineHeight: 1.5, color: "var(--tx)" }}>{q}</span>
            </div>
            <textarea value={vals[i] || ""} onChange={(e) => onChange(i, e.target.value)} rows={2}
              placeholder={"Type your answer…"}
              style={{ width: "100%", resize: "vertical", display: "block",
                background: "var(--bg-1)", border: "1px solid var(--line)", borderRadius: 8, color: "var(--tx)",
                font: "inherit", fontSize: 14.5, padding: "11px 13px", lineHeight: 1.5, outline: "none", transition: "border-color .15s" }}
              onFocus={(e) => e.target.style.borderColor = "var(--accent-line)"}
              onBlur={(e) => e.target.style.borderColor = "var(--line)"} />
          </div>
        ))}
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 16, color: "var(--tx-4)", fontFamily: "var(--mono)", fontSize: 11 }}>
        <span style={{ width: 6, height: 6, borderRadius: "50%", background: saved ? "var(--mint)" : "var(--tx-4)", transition: "background .2s" }}></span>
        {saved ? "Saved to this device" : "Saved privately on this device · never uploaded"}
      </div>
    </section>
  );
}

Object.assign(window, { cls, useStore, loadStore, LS, Marker, ProgressRing, ProgressBar, KnowledgeCheck, ReflectionExercise });
