/* ============================================================
   GUIDED DEPLOYMENT — each player places ships into their zone,
   one at a time, with pass-the-device handoff. Novice-friendly:
   the next ship to place is named; click in the glowing zone.
   ============================================================ */
const { useState: useStateDep, useRef: useRefDep } = React;

// world field constants mirror Board's PlayField
const DF_W = 1240, DF_H = 620, DF_DEPLOY = 150;

function DeployStage({ order, sideShips, sideSquadrons = {}, onDone, onCancel }) {
  // order: [factionA, factionB]; sideShips: {faction: [ships]}; sideSquadrons: {faction: [groepen]}
  const [idx, setIdx] = useStateDep(0);
  const [revealed, setRevealed] = useStateDep(false);
  const [placed, setPlaced] = useStateDep({});     // shipId -> {x,y,facing}
  const [sqPlaced, setSqPlaced] = useStateDep({}); // "faction#flatIdx" -> {x,y}
  const [speeds, setSpeeds] = useStateDep({});     // shipId -> starting speed
  const [view] = useStateDep({ scale: 0.62 });
  const stageRef = useRefDep(null);

  const faction = order[idx];
  const fc = FACTIONS[faction].color;
  const edge = idx === 0 ? "top" : "bottom";
  const myShips = sideShips[faction] || [];
  // squadron-groepen plat maken in dezelfde volgorde als expandSquadrons in App
  const mySquads = [];
  (sideSquadrons[faction] || []).forEach((grp) => {
    for (let i = 0; i < (grp.count || 1); i++) mySquads.push({ key: `${faction}#${mySquads.length}`, name: grp.name });
  });
  const nextShip = myShips.find((s) => !placed[s.id]);
  const allPlaced = !nextShip;
  const nextSquad = allPlaced ? mySquads.find((q) => !sqPlaced[q.key]) : null;
  const allDone = allPlaced && !nextSquad;
  const myPlaced = myShips.filter((s) => placed[s.id]);
  const speedOf = (s) => (speeds[s.id] != null ? speeds[s.id] : (s.speed != null ? s.speed : 2));
  const bumpSpeed = (s, d) => setSpeeds((sp) => {
    const cur = sp[s.id] != null ? sp[s.id] : (s.speed != null ? s.speed : 2);
    return { ...sp, [s.id]: Math.max(0, Math.min(4, cur + d)) };
  });
  const rotateShip = (s, d) => setPlaced((p) => {
    const cur = p[s.id]; if (!cur) return p;
    return { ...p, [s.id]: { ...cur, facing: ((cur.facing + d) % 360 + 360) % 360 } };
  });

  // ---- overlap-preventie: straal per unit + zoek dichtstbijzijnde vrije plek ----
  const allShips = order.flatMap((f) => sideShips[f] || []);
  const SQ_R = 23;
  const shipR = (id) => { const s = allShips.find((x) => x.id === id); return (s ? BASE_SIZES[s.baseSize].px : 80) / 2; };
  const clampToZone = (x, y) => {
    const halfW = DF_W / 2 - 40;
    const zoneTop = edge === "top" ? -DF_H / 2 + 20 : DF_H / 2 - DF_DEPLOY + 20;
    const zoneBot = edge === "top" ? -DF_H / 2 + DF_DEPLOY - 20 : DF_H / 2 - 20;
    return { x: Math.max(-halfW, Math.min(halfW, x)), y: Math.max(zoneTop, Math.min(zoneBot, y)) };
  };
  // bezette plekken (ships + squadrons), optioneel één id/key overslaan
  const occupied = (exceptShipId, exceptSqKey) => [
    ...Object.entries(placed).filter(([id]) => id !== exceptShipId).map(([id, p]) => ({ x: p.x, y: p.y, r: shipR(id) })),
    ...Object.entries(sqPlaced).filter(([k]) => k !== exceptSqKey).map(([, p]) => ({ x: p.x, y: p.y, r: SQ_R })),
  ];
  const hits = (x, y, r, occ) => occ.some((o) => Math.hypot(o.x - x, o.y - y) < (r + o.r) * 0.85);
  // dichtstbijzijnde niet-overlappende plek binnen de zone (spiraal naar buiten)
  const freeSpot = (x, y, r, occ) => {
    const start = clampToZone(x, y);
    if (!hits(start.x, start.y, r, occ)) return start;
    for (let ring = 1; ring < 48; ring++) {
      const rad = ring * (r * 0.8 + 6);
      for (let a = 0; a < 360; a += 18) {
        const c = clampToZone(start.x + Math.cos(a * Math.PI / 180) * rad, start.y + Math.sin(a * Math.PI / 180) * rad);
        if (!hits(c.x, c.y, r, occ)) return c;
      }
    }
    return start; // opgegeven — vol
  };

  // map a click in the stage to world coords, clamped to this player's zone
  const zoneClamp = (e) => {
    const rect = stageRef.current.getBoundingClientRect();
    const sx = e.clientX - rect.left - rect.width / 2;
    const sy = e.clientY - rect.top - rect.height / 2;
    return clampToZone(sx / view.scale, sy / view.scale);
  };
  const place = (e) => {
    if (nextShip) {
      const d = zoneClamp(e);
      const { x, y } = freeSpot(d.x, d.y, shipR(nextShip.id), occupied(nextShip.id));
      setPlaced((p) => ({ ...p, [nextShip.id]: { x, y, facing: edge === "top" ? 180 : 0 } }));
      setSpeeds((sp) => (sp[nextShip.id] != null ? sp : { ...sp, [nextShip.id]: nextShip.speed != null ? nextShip.speed : 2 }));
      return;
    }
    if (nextSquad) {
      const d = zoneClamp(e);
      const { x, y } = freeSpot(d.x, d.y, SQ_R, occupied(null, nextSquad.key));
      setSqPlaced((p) => ({ ...p, [nextSquad.key]: { x, y } }));
    }
  };

  const autoPlace = () => {
    const occ = occupied(); // groeit mee terwijl we plaatsen, zodat auto-plaatsing ook niet overlapt
    const cols = Math.min(Math.max(myShips.length, 1), 6);
    const span = DF_W - 160;
    const add = {};
    myShips.forEach((s, i) => {
      if (placed[s.id]) return;
      const col = i % cols, row = Math.floor(i / cols);
      const gx = (col - (cols - 1) / 2) * (span / Math.max(cols, 1));
      const gy = (edge === "top" ? -DF_H / 2 + 45 : DF_H / 2 - 45) + (edge === "top" ? 1 : -1) * row * 64;
      const r = shipR(s.id);
      const { x, y } = freeSpot(gx, gy, r, occ);
      add[s.id] = { x, y, facing: edge === "top" ? 180 : 0 };
      occ.push({ x, y, r });
    });
    setPlaced((p) => ({ ...p, ...add }));
    setSpeeds((sp) => { const n = { ...sp }; myShips.forEach((s) => { if (n[s.id] == null) n[s.id] = s.speed != null ? s.speed : 2; }); return n; });
    // squadrons in een rij langs de binnenrand van de zone
    const sqCols = Math.min(Math.max(mySquads.length, 1), 8);
    const sqAdd = {};
    mySquads.forEach((q, i) => {
      if (sqPlaced[q.key]) return;
      const col = i % sqCols, row = Math.floor(i / sqCols);
      const gx = (col - (sqCols - 1) / 2) * ((DF_W - 400) / Math.max(sqCols, 1));
      const gy = (edge === "top" ? -DF_H / 2 + DF_DEPLOY - 40 : DF_H / 2 - DF_DEPLOY + 40) + (edge === "top" ? -1 : 1) * row * 40;
      const { x, y } = freeSpot(gx, gy, SQ_R, occ);
      sqAdd[q.key] = { x, y };
      occ.push({ x, y, r: SQ_R });
    });
    setSqPlaced((p) => ({ ...p, ...sqAdd }));
  };

  const undo = () => {
    const lastSq = mySquads.filter((q) => sqPlaced[q.key]).pop();
    if (lastSq && allPlaced) { setSqPlaced((p) => { const n = { ...p }; delete n[lastSq.key]; return n; }); return; }
    const lastPlaced = myShips.filter((s) => placed[s.id]).pop();
    if (lastPlaced) setPlaced((p) => { const n = { ...p }; delete n[lastPlaced.id]; return n; });
  };

  const mergePlacements = () => {
    const out = {};
    Object.keys(placed).forEach((id) => { out[id] = { ...placed[id], speed: speeds[id] != null ? speeds[id] : 2 }; });
    return out;
  };

  const next = () => {
    if (idx + 1 < order.length) { setIdx(idx + 1); setRevealed(false); }
    else onDone(mergePlacements(), sqPlaced);
  };

  return (
    <div className="deploy" style={{ "--fc": fc }}>
      {!revealed ? (
        <div className="scrim" style={{ position: "absolute" }}>
          <div className="dialog cp-dialog" style={{ "--fc": fc }}>
            <div className="cp-handoff">
              <div className="cp-lock">
                <svg width="38" height="38" viewBox="0 0 24 24"><path d="M12 3 L20 7 V12 C20 17 12 22 12 22 C12 22 4 17 4 12 V7 Z" fill="none" stroke="currentColor" strokeWidth="1.5"/></svg>
              </div>
              <div className="cp-handoff-step lbl">Opstellen · {edge === "top" ? "bovenrand" : "onderrand"}</div>
              <h2>Plaats de vloot van <span style={{ color: fc }}>{FACTIONS[faction].name}</span></h2>
              <p>Zet je {myShips.length} schepen in je eigen zone (de gloeiende band). De tegenstander plaatst daarna.</p>
              <button className="btn btn-accent btn-lg" onClick={() => setRevealed(true)}><FactionDot faction={faction} size={11} /> Begin met plaatsen</button>
              {idx === 0 ? <button className="btn btn-ghost" onClick={onCancel} style={{ marginTop: 8 }}>Annuleer</button> : null}
            </div>
          </div>
        </div>
      ) : null}

      <div className="deploy-bar">
        <span className="lbl" style={{ color: fc }}><FactionDot faction={faction} /> {FACTIONS[faction].name} stelt op</span>
        <span className="deploy-prog mono">{myShips.filter((s) => placed[s.id]).length}/{myShips.length} schepen{mySquads.length ? ` · ${mySquads.filter((q) => sqPlaced[q.key]).length}/${mySquads.length} squadrons` : ""}</span>
        <div style={{ flex: 1 }} />
        <button className="btn btn-ghost" onClick={undo} disabled={!myShips.some((s) => placed[s.id]) && !mySquads.some((q) => sqPlaced[q.key])}>Ongedaan</button>
        <button className="btn" onClick={autoPlace} disabled={allDone}>Plaats automatisch</button>
        <button className="btn btn-accent" onClick={next} disabled={!allDone}>{idx + 1 < order.length ? "Klaar — volgende speler →" : "Klaar — begin het potje →"}</button>
      </div>

      <div className="deploy-instr">
        {nextShip ? (
          <>Tik in je zone om <b style={{ color: fc }}>{nextShip.name}</b> ({BASE_SIZES[nextShip.baseSize].name}) te plaatsen. <span className="mono" style={{ color: "var(--text-faint)" }}>Stel daarna per schip de startsnelheid in.</span></>
        ) : nextSquad ? (
          <>Schepen staan. Tik in je zone om squadron <b style={{ color: fc }}>{nextSquad.name}</b> te plaatsen — of gebruik "Plaats automatisch".</>
        ) : <>Alles geplaatst. Stel hieronder de <b style={{ color: fc }}>snelheid en richting</b> per schip in, en klik rechtsboven om door te gaan.</>}
      </div>

      <div className="deploy-stage-wrap">
        <div className="deploy-stage" ref={stageRef} onClick={place}>
          <div className="deploy-world" style={{ transform: `translate(-50%,-50%) scale(${view.scale})` }}>
            <DeployField edge={edge} fc={fc} />
            {myShips.map((s) => {
              const p = placed[s.id]; if (!p) return null;
              const px = BASE_SIZES[s.baseSize].px;
              return (
                <div key={s.id} className="deploy-token" style={{ left: p.x, top: p.y, width: px, height: px, transform: `translate(-50%,-50%) rotate(${p.facing}deg)`, "--fc": fc }}>
                  <ShipHull baseSize={s.baseSize} />
                  <div className="deploy-token-name" style={{ transform: `translate(-50%,-50%) rotate(${-p.facing}deg)` }}>{s.name}</div>
                  <div className="deploy-token-speed" style={{ transform: `rotate(${-p.facing}deg)` }}>SPD {speedOf(s)}</div>
                </div>
              );
            })}
            {mySquads.map((q) => {
              const p = sqPlaced[q.key]; if (!p) return null;
              return (
                <div key={q.key} className="sqd-token" style={{ left: p.x, top: p.y, width: 46, height: 46, transform: "translate(-50%,-50%)", "--fc": fc, position: "absolute" }}>
                  <svg width="46" height="46" viewBox="0 0 46 46">
                    <circle className="sqd-ring" cx="23" cy="23" r="20" />
                    <path className="sqd-wings" d="M23 8 L33 30 L23 25 L13 30 Z" />
                  </svg>
                </div>
              );
            })}
          </div>
        </div>

        {myPlaced.length ? (
          <div className="deploy-speeds">
            <span className="lbl lbl-sm" style={{ color: fc }}>Snelheid &amp; richting</span>
            <div className="deploy-speed-list">
              {myPlaced.map((s) => (
                <div className="deploy-speed-chip" key={s.id}>
                  <ShipGlyph baseSize={s.baseSize} color={fc} size={14} />
                  <span className="dsc-name">{s.name}</span>
                  <div className="dsc-rotate" title="Draai 45°">
                    <button onClick={() => rotateShip(s, -45)} aria-label="draai links">↺</button>
                    <span className="dsc-deg mono">{placed[s.id].facing}°</span>
                    <button onClick={() => rotateShip(s, 45)} aria-label="draai rechts">↻</button>
                  </div>
                  <div className="stepper">
                    <button onClick={() => bumpSpeed(s, -1)} disabled={speedOf(s) <= 0}>{"−"}</button>
                    <div className="val"><span>{speedOf(s)}</span></div>
                    <button onClick={() => bumpSpeed(s, +1)} disabled={speedOf(s) >= 4}>+</button>
                  </div>
                </div>
              ))}
            </div>
          </div>
        ) : null}
      </div>
    </div>
  );
}

function DeployField({ edge, fc }) {
  const W = DF_W, H = DF_H, P = 60;
  const svgW = W + P * 2, svgH = H + P * 2, L = P, T = P, R = P + W, B = P + H;
  const myBandY = edge === "top" ? T : B - DF_DEPLOY;
  return (
    <svg className="deploy-fieldsvg" width={svgW} height={svgH} viewBox={`0 0 ${svgW} ${svgH}`} style={{ left: -(P + W / 2), top: -(P + H / 2) }}>
      <rect className="field-surface" x={L} y={T} width={W} height={H} rx="6" />
      <rect className="deploy-zone-mine" x={L} y={myBandY} width={W} height={DF_DEPLOY} style={{ "--zc": fc }} />
      <line className="field-center" x1={L} y1={T + H / 2} x2={R} y2={T + H / 2} />
      <rect className="field-border" x={L} y={T} width={W} height={H} rx="6" />
      <text className="deploy-zone-lbl" x={L + 16} y={myBandY + (edge === "top" ? 30 : DF_DEPLOY - 16)} style={{ "--zc": fc }}>JOUW ZONE</text>
    </svg>
  );
}

Object.assign(window, { DeployStage });
