/* ============================================================
   TUTORIAL — scripted, spotlighted walkthrough of a first turn.
   Advances on real app state (ctx) or on DOM presence of targets,
   so it stays in sync even through the planner/attack dialogs.
   ============================================================ */
const { useState: useStateTut, useEffect: useEffTut, useRef: useRefTut } = React;

/* Each step:
   - title, body            text
   - target                 CSS selector to spotlight (omit = centered card)
   - place                  'auto' | 'top' | 'bottom' (tooltip side)
   - await(ctx)             advance when returns true (state-driven)
   - awaitSel               advance when selector EXISTS in DOM
   - goneSel                advance when selector is ABSENT from DOM
   - manual                 show a "Volgende" button (info steps)
*/
const TUT_STEPS = [
  { title: "Welkom aan boord, commandant", manual: true,
    body: "Ik leid je één keer door een beurt. Volg de gloeiende markeringen en lees de tekst — je leert het al doende. Klik 'Volgende' om te beginnen." },
  { title: "De fase-balk", target: ".phase-rail", place: "bottom", manual: true,
    body: "Bovenaan zie je de vier fasen van elke ronde: Command, Ship, Squadron en Status. De actieve fase licht op." },
  { title: "Wiens beurt is het?", target: ".hotseat .player-pills", place: "bottom", manual: true,
    body: "Hier zie je welke speler aan zet is. In een hotseat-potje geef je het apparaat door; de app houdt bij wie wat al deed." },
  { title: "1 · Command-fase", target: ".flow-banner .btn-accent", place: "bottom",
    awaitSel: ".cp-dialog",
    body: "Elke ronde plan je eerst in het geheim wat je schepen doen. Klik op 'Plan commands'." },
  { title: "Geef het door", target: ".cp-handoff .btn-accent", place: "auto",
    awaitSel: ".cp-ship",
    body: "Normaal geef je het scherm aan die speler zodat de ander niets ziet. Klik om je planscherm te onthullen." },
  { title: "Kies opdrachten", target: ".cp-dialog", place: "auto",
    await: (c) => c.phase === "ship",
    body: "Tik per schip een opdracht: NAV (bewegen), SQ (jagers), REP (herstel) of CF (extra vuurkracht). Klik dan 'Klaar' — en doe hetzelfde voor de tweede speler." },
  { title: "2 · Ship-fase", target: ".flow-banner", place: "bottom",
    await: (c) => c.selectedActivatable,
    body: "Nu is het jouw beurt. Je schepen die nog mogen activeren lichten op het bord op. Tik er één — of gebruik een chip in deze balk." },
  { title: "Activeer het schip", target: ".flow-banner .btn-accent", place: "bottom",
    await: (c) => c.hasInProgress,
    body: "Klik 'Activeer — onthul dial' om de geplande opdracht van dit schip om te draaien en de beurt te starten." },
  { title: "De onthulde dial", target: ".flow-banner", place: "bottom", manual: true,
    body: "De dial bepaalt je extraatje deze activatie: NAV = ±1 snelheid en een extra stuurklik, SQ = squadrons activeren, REP = engineering-punten (herstel hull/shields via het schip-paneel), CF = een extra aanvalsdie." },
  { title: "Open het vuren", target: ".flow-banner", place: "bottom",
    awaitSel: ".ar-dialog",
    body: "Een schip mag vuren en bewegen. Klik op 'Aanval' om het gevecht te openen." },
  { title: "Kies een doel", target: ".ar-targets", place: "auto",
    awaitSel: ".ar-tray .die",
    body: "Kies een vijandig schip dat 'in bereik' staat (groene 'Vuur'). De app pakt automatisch de juiste dice voor die afstand en hoek." },
  { title: "De worp", target: ".ar-tallies", place: "top", manual: true,
    body: "De app rolde je aanvalsdice en telde de uitkomst: schade, crits en accuracy. ▲ = schade, ✦ = crit, ◎ = accuracy (vergrendelt een verdedig-token)." },
  { title: "Naar de verdediging", target: ".dialog-inline-foot .btn-accent", place: "top",
    awaitSel: ".ar-preview",
    body: "Klik door naar de verdedigingsstap." },
  { title: "Verdedig & reken uit", target: ".ar-preview", place: "top",
    awaitSel: ".ar-done",
    body: "De verdediger mag tokens inzetten (Brace, Redirect…). De app trekt de schade af van shields en dan hull. Klik 'Pas schade toe'." },
  { title: "Schade toegepast", target: ".ar-done", place: "auto", manual: true,
    body: "Klaar! De schade staat verwerkt en in het logboek. Sluit dit venster met 'Klaar'." },
  { title: "Manoeuvreren", target: ".flow-banner", place: "bottom",
    awaitSel: ".mv-layer",
    body: "Nu bewegen: klik op 'Manoeuvre'. Er verschijnt een virtuele beweegliniaal vanaf je schip." },
  { title: "Stuur en bevestig", target: ".mv-end-ctrls", place: "top",
    goneSel: ".mv-layer",
    body: "Elke ◄ ► knop buigt het pad één klik (snelheid = aantal segmenten; met een Navigate-dial mag één gewricht een extra klik en pas je de snelheid aan). Klik '✓ Verplaats' om de beweging uit te voeren." },
  { title: "Beëindig je beurt", target: ".flow-banner", place: "bottom",
    await: (c) => !c.hasInProgress && c.phase === "ship",
    body: "Klaar met dit schip? Klik 'Beëindig' — de beurt gaat naar de tegenstander." },
  { title: "3 · Squadron-fase", manual: true,
    body: "Na alle schepen komen de squadrons: spelers wisselen af met 2 activaties per beurt (of eerder al via een Squadron-dial). Tik een squadron, sleep het, rol de aanval op een doel binnen bereik, en klik 'Klaar ✓'." },
  { title: "4 · Status-fase", manual: true,
    body: "Aan het einde van de ronde worden uitgeputte defense tokens weer ready, wisselt het initiatief naar de andere speler, en begint een nieuwe ronde. Na 6 rondes wint wie de meeste punten vernietigde (plus objectief-punten uit het scorepaneel)." },
  { title: "Zo speel je verder", manual: true, finish: true,
    body: "Dat is een complete activatie! Spelers wisselen af tot alle schepen geweest zijn, daarna volgen de Squadron- en Status-fase (de balk vertelt je steeds wat te doen, en de '?' legt elke fase uit). Veel plezier!" },
];

function Tutorial({ ctx, onFinish }) {
  const [idx, setIdx] = useStateTut(0);
  const [rect, setRect] = useStateTut(null);
  const [stuck, setStuck] = useStateTut(false);
  const idxRef = useRefTut(0); idxRef.current = idx;
  const stepStartRef = useRefTut(Date.now());

  const step = TUT_STEPS[idx];

  // advance checks (state + DOM), and reposition spotlight
  useEffTut(() => {
    let raf;
    const tick = () => {
      const s = TUT_STEPS[idxRef.current];
      if (!s) return;
      // reposition
      let targetFound = true;
      if (s.target) {
        const el = document.querySelector(s.target);
        if (el) {
          const r = el.getBoundingClientRect();
          setRect({ x: r.left, y: r.top, w: r.width, h: r.height });
        } else { setRect(null); targetFound = false; }
      } else setRect(null);
      // auto-advance
      if (!s.manual) {
        let go = false;
        if (s.await && s.await(ctx)) go = true;
        if (s.awaitSel && document.querySelector(s.awaitSel)) go = true;
        if (s.goneSel && !document.querySelector(s.goneSel) && (!s.await || s.await(ctx))) {
          // goneSel combined with await handled above; standalone gone:
          if (!s.await) go = true;
        }
        if (go) setIdx((i) => Math.min(i + 1, TUT_STEPS.length - 1));
        else {
          // fallback: target onvindbaar (>8s) of stap hangt (>30s) → "Sla stap over" tonen
          const waited = Date.now() - stepStartRef.current;
          setStuck((!targetFound && waited > 8000) || waited > 30000);
        }
      }
      raf = setTimeout(tick, 250);
    };
    tick();
    return () => clearTimeout(raf);
  }, [ctx]);

  // recompute rect immediately on step change
  useEffTut(() => {
    stepStartRef.current = Date.now();
    setStuck(false);
    if (step.target) {
      const el = document.querySelector(step.target);
      if (el) { const r = el.getBoundingClientRect(); setRect({ x: r.left, y: r.top, w: r.width, h: r.height }); }
      else setRect(null);
    } else setRect(null);
  }, [idx]);

  const next = () => { if (step.finish) onFinish(); else setIdx((i) => Math.min(i + 1, TUT_STEPS.length - 1)); };

  // tooltip position
  const pad = 8;
  let tipStyle = {};
  let placement = "center";
  if (rect) {
    const place = step.place === "top" ? "top" : step.place === "bottom" ? "bottom"
      : (rect.y > window.innerHeight * 0.5 ? "top" : "bottom");
    placement = place;
    const cx = Math.min(Math.max(rect.x + rect.w / 2, 200), window.innerWidth - 200);
    if (place === "bottom") tipStyle = { left: cx, top: rect.y + rect.h + pad + 10, transform: "translateX(-50%)" };
    else tipStyle = { left: cx, top: rect.y - pad - 10, transform: "translate(-50%,-100%)" };
  }

  return (
    <div className="tut-layer">
      {rect ? (
        <div className="tut-hole" style={{ left: rect.x - 6, top: rect.y - 6, width: rect.w + 12, height: rect.h + 12 }} />
      ) : (
        <div className="tut-dim" />
      )}

      <div className={"tut-card" + (rect ? " anchored" : " centered")} style={rect ? tipStyle : null} data-place={placement}>
        <div className="tut-step mono">Stap {idx + 1}/{TUT_STEPS.length}</div>
        <div className="tut-title">{step.title}</div>
        <div className="tut-body">{step.body}</div>
        <div className="tut-foot">
          <button className="tut-skip" onClick={onFinish}>Tutorial sluiten</button>
          <div style={{ flex: 1 }} />
          {step.manual ? (
            <button className="btn btn-accent" onClick={next}>{step.finish ? "Klaar — zelf spelen" : "Volgende →"}</button>
          ) : stuck ? (
            <button className="btn" onClick={next} title="Lukt het niet? Ga door naar de volgende stap.">Sla stap over →</button>
          ) : (
            <span className="tut-wait mono">↑ doe de gemarkeerde actie</span>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Tutorial, TUT_STEPS });
