/* ============================================================
   MTOPS Academy — interactive diagrams
   Simple, geometric, animated. Complex visuals fall back to placeholders.
   ============================================================ */

function DiagramFrame({ label, hint, children, foot }) {
  return (
    <figure className="panel ticked" style={{ margin: "6px 0 0", padding: "16px 16px 14px", overflow: "hidden" }}>
      <figcaption style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, marginBottom: 12, flexWrap: "wrap" }}>
        <span className="eyebrow" style={{ color: "var(--accent)" }}>{label}</span>
        {hint && <span className="mono" style={{ fontSize: 10.5, color: "var(--tx-4)" }}>{hint}</span>}
      </figcaption>
      {children}
      {foot && <p style={{ margin: "12px 2px 2px", fontSize: 12.5, color: "var(--tx-3)", lineHeight: 1.5 }}>{foot}</p>}
    </figure>
  );
}

/* ---------- 1. Cycle wave: 10 turning points ---------- */
function CycleWave() {
  const W = 760, H = 230, mid = 118, amp = 64, periods = 5;
  // Layered noise, windowed by |cos| so it vanishes exactly at each turning point — keeps tops/bottoms pinned to the markers while chopping like live price between them.
  const noise = (x) => Math.sin(x * 0.09 + 0.5) * 0.50 + Math.sin(x * 0.23 + 1.7) * 0.30 + Math.sin(x * 0.50 + 2.9) * 0.22 + Math.sin(x * 0.84 + 0.4) * 0.14;
  const val = (x) => {
    const arg = (2 * Math.PI * periods * x) / W;
    return mid - amp * Math.sin(arg) - amp * 0.26 * noise(x) * Math.abs(Math.cos(arg));
  };
  const pts = [];
  for (let x = 0; x <= W; x += 2) pts.push([x, val(x)]);
  const path = "M" + pts.map((p) => `${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(" L");
  const tps = [];
  for (let k = 0; k < 2 * periods; k++) {
    const theta = Math.PI / 2 + k * Math.PI;
    const x = (theta * W) / (2 * Math.PI * periods);
    const top = Math.sin((2 * Math.PI * periods * x) / W) > 0; // sin>0 => y<mid => top
    tps.push({ x, y: mid - amp * Math.sin((2 * Math.PI * periods * x) / W), top, n: k + 1 });
  }
  const [play, setPlay] = useState(false);
  const [t, setT] = useState(1);
  const raf = useRef(0);
  useEffect(() => {
    if (!play) return;
    let start;
    const step = (ts) => {
      if (!start) start = ts;
      const p = Math.min(1, (ts - start) / 3200);
      setT(p);
      if (p < 1) raf.current = requestAnimationFrame(step); else setPlay(false);
    };
    setT(0); raf.current = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf.current);
  }, [play]);
  const headX = t * W;
  const headY = val(headX);

  return (
    <DiagramFrame label="Anatomy of a cycle" hint="10 turning points · 5 tops · 5 bottoms"
      foot="Every cycle resolves through ten turning points regardless of market or timeframe. The midline marks the balance of finite cycle energy.">
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: "block" }}>
        {[0, 1, 2, 3].map((q) => <line key={q} x1={(q + 1) * W / 4} y1="14" x2={(q + 1) * W / 4} y2={H - 30} stroke="var(--line)" strokeDasharray="3 5" />)}
        <line x1="0" y1={mid} x2={W} y2={mid} stroke="var(--line-2)" strokeDasharray="2 6" />
        <text x="6" y={mid - 6} className="mono" fontSize="9" fill="var(--tx-4)">MIDLINE</text>
        <path d={path} fill="none" stroke="var(--accent)" strokeWidth="2.4"
          strokeDasharray={W * 3} strokeDashoffset={(1 - t) * W * 3}
          style={{ filter: "drop-shadow(0 0 6px var(--accent-glow))" }} />
        {tps.map((tp) => {
          const shown = tp.x / W <= t + 0.001;
          return (
            <g key={tp.n} opacity={shown ? 1 : 0} style={{ transition: "opacity .25s" }}>
              <circle cx={tp.x} cy={tp.y} r="6.5" fill="var(--bg)" stroke={tp.top ? "var(--mint)" : "var(--amber)"} strokeWidth="2" />
              <text x={tp.x} y={tp.top ? tp.y - 13 : tp.y + 20} textAnchor="middle" className="mono" fontSize="10"
                fill={tp.top ? "var(--mint)" : "var(--amber)"}>{tp.n}</text>
            </g>
          );
        })}
        {play && <circle cx={headX} cy={headY} r="4" fill="#fff" style={{ filter: "drop-shadow(0 0 6px #fff)" }} />}
      </svg>
      <div style={{ display: "flex", gap: 16, alignItems: "center", marginTop: 4 }}>
        <button className="btn accent" onClick={() => setPlay(true)} disabled={play}>{play ? "TRACING…" : "▶ TRACE CYCLE"}</button>
        <span className="mono" style={{ fontSize: 11, color: "var(--mint)" }}>● tops</span>
        <span className="mono" style={{ fontSize: 11, color: "var(--amber)" }}>● bottoms</span>
      </div>
    </DiagramFrame>
  );
}

/* ---------- 2. Gann square (5x5) ---------- */
function GannSquare() {
  const N = 5, S = 320, cell = S / N, pad = 26;
  const [show11, setShow11] = useState(true);
  const [show12, setShow12] = useState(false);
  const [showArc, setShowArc] = useState(false);
  const x = (i) => pad + i * cell, y = (i) => pad + (N - i) * cell; // origin bottom-left
  return (
    <DiagramFrame label="The Gann Square" hint="5 × 5 grid · origin bottom-left"
      foot="The 1×1 angle rises at 45° — one box across, one box up — and reads as the market's natural direction. Steeper or shallower ratios (1×2, 2×1) map faster or slower paths; resistance arcs act as capture nets.">
      <svg viewBox={`0 0 ${S + pad * 2} ${S + pad * 2}`} width="100%" style={{ display: "block", maxWidth: 360, margin: "0 auto" }}>
        {Array.from({ length: N + 1 }).map((_, i) => (
          <g key={i} stroke="var(--line-2)" strokeWidth="1">
            <line x1={x(i)} y1={pad} x2={x(i)} y2={pad + S} />
            <line x1={pad} y1={y(i)} x2={pad + S} y2={y(i)} />
          </g>
        ))}
        {showArc && [1, 2, 3, 4, 5].map((r) => (
          <path key={r} d={`M ${x(r)} ${y(0)} A ${r * cell} ${r * cell} 0 0 1 ${x(0)} ${y(r)}`}
            fill="none" stroke="var(--blue)" strokeWidth="1.3" opacity={0.5 + r * 0.08} />
        ))}
        {show11 && <line x1={x(0)} y1={y(0)} x2={x(5)} y2={y(5)} stroke="var(--mint)" strokeWidth="2.4" style={{ filter: "drop-shadow(0 0 5px var(--mint-glow))" }} />}
        {show11 && <text x={x(5) - 4} y={y(5) + 2} textAnchor="end" className="mono" fontSize="11" fill="var(--mint)">1×1 · 45°</text>}
        {show12 && <line x1={x(0)} y1={y(0)} x2={x(5)} y2={y(2.5)} stroke="var(--amber)" strokeWidth="2.2" />}
        {show12 && <text x={x(5) - 4} y={y(2.5) - 6} textAnchor="end" className="mono" fontSize="11" fill="var(--amber)">1×2</text>}
        <circle cx={x(0)} cy={y(0)} r="4" fill="var(--accent)" />
      </svg>
      <div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginTop: 6 }}>
        <button className={cls("btn", show11 && "accent")} onClick={() => setShow11((v) => !v)}>1×1 · 45°</button>
        <button className={cls("btn", show12 && "accent")} onClick={() => setShow12((v) => !v)}>1×2 angle</button>
        <button className={cls("btn", showArc && "accent")} onClick={() => setShowArc((v) => !v)}>Resistance arcs</button>
      </div>
    </DiagramFrame>
  );
}

/* ---------- 3. Kill zone: impulse energy wheel ---------- */
function KillZone() {
  const [energy, setEnergy] = useState(30);
  const S = 220, c = S / 2, R = 86;
  const spokes = 16;
  const hi = energy > 66, mid = energy > 33;
  const col = hi ? "var(--red)" : mid ? "var(--amber)" : "var(--mint)";
  const state = hi ? "HIGH — significant move building" : mid ? "RISING — transition forming" : "LOW — calm market";
  // Needle sweeps 33°→66° (compass: 0°=N, 180°=S). Impulse = circle of candles expanding from the turning point.
  const angleDeg = 66 - (energy / 100) * 33;
  const rad = angleDeg * Math.PI / 180;
  const rImp = R * (energy / 100);
  const nx = c + Math.sin(rad) * rImp;
  const ny = c - Math.cos(rad) * rImp;
  return (
    <DiagramFrame label="The Kill Zone" hint="impulse energy → next transition"
      foot="The impulse is the circle of candles expanding outward from the turning point at its centre: a small circle is a calm market, a wide one signals a significant move. Avoid trading inside the zone — wait for the squaring of price and time before acting.">
      <div style={{ display: "flex", gap: 22, alignItems: "center", flexWrap: "wrap", justifyContent: "center" }}>
        <svg viewBox={`0 0 ${S} ${S}`} width="200" height="200" style={{ flex: "none" }}>
          <circle cx={c} cy={c} r={R} fill="none" stroke="var(--line-2)" strokeWidth="1" />
          {Array.from({ length: spokes }).map((_, i) => {
            const a = (i / spokes) * 2 * Math.PI;
            return <line key={i} x1={c} y1={c} x2={c + Math.cos(a) * R} y2={c + Math.sin(a) * R}
              stroke="var(--line-2)" strokeWidth="1" opacity="0.4" />;
          })}
          <circle cx={c} cy={c} r={rImp} fillOpacity="0.12" strokeWidth="2.5"
            style={{ stroke: col, fill: col, filter: `drop-shadow(0 0 ${energy / 10}px ${col})` }} />
          <line x1={c} y1={c} x2={nx} y2={ny}
            strokeWidth="3" strokeLinecap="round" style={{ stroke: col, filter: `drop-shadow(0 0 4px ${col})` }} />
          <circle cx={c} cy={c} r="5" style={{ fill: col }} />
        </svg>
        <div style={{ minWidth: 180, flex: 1 }}>
          <div className="mono" style={{ fontSize: 13, color: col, marginBottom: 4 }}>{energy}% IMPULSE</div>
          <div style={{ fontSize: 13.5, color: "var(--tx-2)", marginBottom: 16, minHeight: 38 }}>{state}</div>
          <input type="range" min="0" max="100" value={energy} onChange={(e) => setEnergy(+e.target.value)}
            style={{ width: "100%", accentColor: col }} />
          <div className="mono" style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "var(--tx-4)", marginTop: 4 }}>
            <span>CALM</span><span>VOLATILE</span>
          </div>
        </div>
      </div>
    </DiagramFrame>
  );
}

/* ---------- 4. Time-cycle ladder ---------- */
function Ladder() {
  const rungs = [
    { m: 2, use: "Scalping volatile markets", t: "high-freq" },
    { m: 8, use: "Day trading", t: "intraday" },
    { m: 32, use: "Swing trading — start here", t: "core", core: true },
    { m: 128, use: "Trend context", t: "context" },
    { m: 512, use: "Dominant trend · days of lead", t: "macro" },
    { m: 2048, use: "Major-trend confirmation", t: "aerial" },
  ];
  const max = Math.log2(2048);
  const [sel, setSel] = useState(2);
  return (
    <DiagramFrame label="The time-cycle ladder" hint="related by powers of four"
      foot="Cycle lengths are mathematically linked — 32 → 128 → 512 — structured by the number four. Master the 32-minute cycle before stacking multiple frames.">
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {rungs.map((r, i) => {
          const w = (Math.log2(r.m) / max) * 100;
          const active = sel === i;
          return (
            <button key={r.m} onClick={() => setSel(i)} style={{ display: "flex", alignItems: "center", gap: 12, background: "none", border: "none", cursor: "pointer", padding: 0, textAlign: "left" }}>
              <span className="mono" style={{ width: 54, flex: "none", fontSize: 12.5, color: active ? "var(--accent)" : "var(--tx-3)" }}>{r.m}m</span>
              <span style={{ flex: 1, position: "relative", height: 26 }}>
                <span style={{ position: "absolute", inset: 0, background: "var(--bg-1)", borderRadius: 5 }} />
                <span style={{ position: "absolute", top: 0, left: 0, bottom: 0, width: `${w}%`, borderRadius: 5,
                  background: r.core ? "var(--accent)" : (active ? "var(--accent)" : "var(--line-2)"),
                  opacity: r.core || active ? 1 : 0.8, transition: "all .2s",
                  boxShadow: active ? "0 0 14px var(--accent-glow)" : "none" }} />
                <span style={{ position: "absolute", left: 10, top: 0, bottom: 0, display: "flex", alignItems: "center",
                  fontSize: 12, color: (active && w > 30) ? "var(--bg)" : "var(--tx-2)", fontWeight: active ? 600 : 400 }}>{r.use}</span>
              </span>
            </button>
          );
        })}
      </div>
    </DiagramFrame>
  );
}

/* ---------- 5. Leverage amplifier ---------- */
function Leverage() {
  const [lev, setLev] = useState(10);
  const base = 100;
  const power = base * lev;
  const liqMove = (100 / lev).toFixed(1);
  return (
    <DiagramFrame label="Leverage amplifier" hint="$100 account"
      foot="Leverage multiplies exposure — and risk. A larger multiplier means a smaller adverse move wipes the position. Manage it with stop losses and isolated margin.">
      <div style={{ display: "flex", gap: 14, flexWrap: "wrap", marginBottom: 18 }}>
        {[{ k: "Buying power", v: `$${power.toLocaleString()}`, c: "var(--mint)" },
          { k: "Multiplier", v: `${lev}×`, c: "var(--tx)" },
          { k: "Liquidation move", v: `−${liqMove}%`, c: lev > 12 ? "var(--red)" : "var(--amber)" }].map((s) => (
          <div key={s.k} style={{ flex: "1 1 110px", background: "var(--bg-1)", border: "1px solid var(--line)", borderRadius: 8, padding: "12px 14px" }}>
            <div className="eyebrow" style={{ marginBottom: 6 }}>{s.k}</div>
            <div className="mono" style={{ fontSize: 22, color: s.c, transition: "color .2s" }}>{s.v}</div>
          </div>
        ))}
      </div>
      <input type="range" min="1" max="25" value={lev} onChange={(e) => setLev(+e.target.value)} style={{ width: "100%", accentColor: lev > 12 ? "var(--red)" : "var(--mint)" }} />
      <div className="mono" style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "var(--tx-4)", marginTop: 4 }}>
        <span>1× SPOT</span><span>25× MAX RISK</span>
      </div>
    </DiagramFrame>
  );
}

/* ---------- 6. Three-question gate ---------- */
function ThreeQuestionGate() {
  const qs = ["Am I trading from strength?", "Am I with the trend?", "Is price outside the zone?"];
  const [ans, setAns] = useState([null, null, null]);
  const allYes = ans.every((a) => a === true);
  const anyNo = ans.some((a) => a === false);
  const verdict = ans.every((a) => a != null) ? (allYes ? "trade" : "stay") : null;
  return (
    <DiagramFrame label="The three-question check" hint="all yes, or stay out"
      foot="Run this before every entry. A single “no” means the setup isn't there — protecting capital is the trade.">
      <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
        {qs.map((q, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 12, background: "var(--bg-1)", border: "1px solid var(--line)", borderRadius: 8, padding: "12px 14px" }}>
            <span className="mono" style={{ color: "var(--accent)", fontSize: 12, flex: "none" }}>{String(i + 1).padStart(2, "0")}</span>
            <span style={{ flex: 1, fontSize: 14.5 }}>{q}</span>
            {["YES", "NO"].map((lab, li) => {
              const on = ans[i] === (li === 0);
              const c = li === 0 ? "var(--mint)" : "var(--red)";
              return (
                <button key={lab} onClick={() => setAns((p) => p.map((v, j) => j === i ? (li === 0) : v))}
                  className="mono" style={{ fontSize: 11, padding: "6px 12px", borderRadius: 6, cursor: "pointer",
                    border: `1px solid ${on ? c : "var(--line-2)"}`, color: on ? "var(--bg)" : "var(--tx-3)",
                    background: on ? c : "transparent", transition: "all .15s" }}>{lab}</button>
              );
            })}
          </div>
        ))}
      </div>
      {verdict && (
        <div className="fade-in" style={{ marginTop: 14, padding: "14px 18px", borderRadius: 8, textAlign: "center",
          border: `1px solid ${allYes ? "var(--line-mint)" : "rgba(239,90,107,.4)"}`,
          background: allYes ? "var(--mint-soft)" : "var(--red-soft)",
          color: allYes ? "var(--mint)" : "var(--red)", fontFamily: "var(--mono)", letterSpacing: ".1em" }}>
          {allYes ? "✓ CONDITIONS MET — A TRADE MAY BE THERE" : "✕ STAY OUT — PROTECT CAPITAL"}
        </div>
      )}
    </DiagramFrame>
  );
}

/* ---------- placeholder for complex visuals ---------- */
function DiagramPlaceholder({ tag, label }) {
  return <div className="ph" style={{ minHeight: 150, marginTop: 6 }}>
    <span className="ph-tag">{tag}</span>
    <span style={{ color: "var(--tx-3)" }}>{label}</span>
  </div>;
}

window.DIAGRAMS = { cycle: CycleWave, gann: GannSquare, killzone: KillZone, ladder: Ladder, leverage: Leverage, gate: ThreeQuestionGate };
Object.assign(window, { DiagramFrame, DiagramPlaceholder });
