/* ============================================================
   SQUADRON TOKEN + PANEL — board tokens with hull/activation,
   simple anti-squadron / anti-ship attack roll
   ============================================================ */
const { useState: useStateSq, useRef: useRefSq, useMemo: useMemoSq } = React;

function SquadronToken({ sq, selected, zoom, eligible, locked, movable = true, onSelect, onMove, onDragState }) {
  const fc = FACTIONS[sq.faction].color;
  const drag = useRefSq(null);
  const px = 46;
  const maxMove = (sq.speed || 3) * SQD_MOVE; // sleepafstand begrensd op snelheid

  const onPointerDown = (e) => {
    e.stopPropagation();
    e.currentTarget.setPointerCapture(e.pointerId);
    drag.current = { x0: e.clientX, y0: e.clientY, sx: sq.x, sy: sq.y, moved: false };
  };
  const onPointerMove = (e) => {
    const d = drag.current; if (!d || !movable) return;
    const dx = e.clientX - d.x0, dy = e.clientY - d.y0;
    if (!d.moved && Math.hypot(dx, dy) > 3) { d.moved = true; onDragState && onDragState(true); }
    if (d.moved) {
      let nx = d.sx + dx / zoom, ny = d.sy + dy / zoom;
      const dist = Math.hypot(nx - d.sx, ny - d.sy); // niet verder dan maxMove van de startplek
      if (dist > maxMove) { const k = maxMove / dist; nx = d.sx + (nx - d.sx) * k; ny = d.sy + (ny - d.sy) * k; }
      onMove(sq.id, nx, ny);
    }
  };
  const onPointerUp = (e) => {
    const d = drag.current; drag.current = null;
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch (_) {}
    if (d && d.moved) onDragState && onDragState(false); else onSelect(sq.id);
  };

  const hullPct = sq.maxHull ? sq.hull / sq.maxHull : 1;
  const cls = sq.hull <= 0 ? "crit" : hullPct <= 0.4 ? "low" : "";

  return (
    <div className="sqd-token" data-selected={selected} data-destroyed={sq.hull <= 0} data-activated={sq.activated} data-eligible={eligible || undefined} data-locked={locked || undefined}
         style={{ left: sq.x, top: sq.y, width: px, height: px, transform: "translate(-50%,-50%)", "--fc": fc }}
         onPointerDown={locked ? undefined : onPointerDown} onPointerMove={locked ? undefined : onPointerMove} onPointerUp={locked ? undefined : onPointerUp} onPointerCancel={locked ? undefined : onPointerUp}>
      {selected && !sq.destroyed ? (
        <svg className="sqd-move-range" width={maxMove * 2} height={maxMove * 2} viewBox={`0 0 ${maxMove * 2} ${maxMove * 2}`}
             style={{ position: "absolute", left: "50%", top: "50%", marginLeft: -maxMove, marginTop: -maxMove, pointerEvents: "none", overflow: "visible" }}>
          <circle cx={maxMove} cy={maxMove} r={maxMove - 1} />
        </svg>
      ) : null}
      {eligible ? <div className="sqd-eligible-ring" /> : null}
      <svg width={px} height={px} 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>
      <span className={"sqd-hull num " + cls}>{sq.hull}</span>
    </div>
  );
}

function SquadronPanel({ sq, phase, guided, g, sqCmdShipFaction, squadrons = [], ships = [], onUpdate, onActivate, onFinish, onDamageSquadron, onDamageShip, onRemove }) {
  const [roll, setRoll] = useStateSq(null);
  const [mode, setMode] = useStateSq("antiSquad");
  const [targetId, setTargetId] = useStateSq(null);
  const fc = FACTIONS[sq.faction].color;

  const myTurn = squadronActivatable(sq, g, phase, sqCmdShipFaction);
  const attacked = !!sq.attacked; // één aanval per activatie

  // legale doelen + blokkade-reden komen uit de gedeelde engagement/keyword-logica
  const atk = useMemoSq(() => squadronAttackTargets(sq, squadrons, ships, mode), [sq, squadrons, ships, mode]);
  const targets = mode === "antiSquad" ? atk.squads : atk.ships;
  const blockReason = atk.reason;
  const target = targets.find((t) => t.id === targetId) || null;
  const isBomber = sq.keywords.includes("Bomber");

  // Swarm-herrol: geldt alleen antiSquad, en alleen als het doelwit door een ANDER eigen squadron geëngageerd wordt
  // Swarm: het doel moet door een ánder (niet-Heavy) bevriend squadron geëngageerd zijn
  const targetEngagedByAlly = mode === "antiSquad" && target
    ? squadrons.some((o) => o.id !== sq.id && o.faction === sq.faction && !o.destroyed && !hasKw(o, "heavy") && sqDist(o, target) <= SQD_ENGAGE_RANGE)
    : false;

  const doRoll = () => {
    if (attacked || blockReason) return;
    const pool = mode === "antiSquad" ? sq.antiSquad : sq.antiShip;
    let dice = rollPool(pool);
    dice = applySquadronRerolls(sq, dice, rollFace, targetEngagedByAlly);
    const tally = dice.reduce((a, d) => { const v = FACE_VALUE[d.face]; a.dmg += v.dmg; a.crit += v.crit; a.acc += v.acc; return a; }, { dmg: 0, crit: 0, acc: 0 });
    setRoll({ dice, tally, applied: false });
  };

  const applyRoll = () => {
    if (!roll || !target || roll.applied || attacked || !myTurn) return;
    if (phase === "squadron" && !squadronMayAct(sq, "attack", { moved: sq.moved, attacked: sq.attacked })) return;
    if (mode === "antiSquad") onDamageSquadron && onDamageSquadron(sq.id, target.id, roll.tally.dmg);
    else onDamageShip && onDamageShip(sq.id, target.id, roll.tally.dmg, roll.tally.crit);
    setRoll((r) => ({ ...r, applied: true }));
    onUpdate(sq.id, { attacked: true }); // markeer: deze activatie is de aanval gebruikt
  };

  const canFinish = !sq.activated && onFinish && (phase === "squadron" || phase === "ship");

  return (
    <div style={{ "--fc": fc }}>
      <div className="sec-head" style={{ "--sec-accent": fc }}>
        <span className="sec-accent" style={{ background: fc }} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
            <svg width="15" height="15" viewBox="0 0 14 14" style={{ color: fc }}><circle cx="3.5" cy="7" r="2" fill="currentColor"/><circle cx="10.5" cy="4" r="2" fill="currentColor"/><circle cx="10.5" cy="10" r="2" fill="currentColor"/></svg>
            <span className="lbl" style={{ color: "var(--text)", fontSize: 13 }}>{sq.name}</span>
          </div>
          <div className="mono" style={{ fontSize: 10.5, color: "var(--text-faint)", marginTop: 2 }}>
            Squadron · {FACTIONS[sq.faction].name}{sq.keywords.length ? " · " + sq.keywords.join(", ") : ""}
          </div>
        </div>
        <button className="icon-btn btn-danger" onClick={() => onRemove(sq.id)} style={{ color: "var(--bad)", borderColor: "color-mix(in oklab, var(--bad), transparent 55%)" }}>
          <svg width="15" height="15" viewBox="0 0 16 16"><path d="M3 4 H13 M6.5 4 V2.5 H9.5 V4 M4.5 4 L5 13.5 H11 L11.5 4" fill="none" stroke="currentColor" strokeWidth="1.3"/></svg>
        </button>
      </div>

      <div className="sec-body">
        <div className="stat-row">
          <div className="stat-label"><span className="lbl">Hull</span></div>
          <Stepper value={sq.hull} min={0} max={sq.maxHull} showMax={sq.maxHull} onChange={(v) => onUpdate(sq.id, { hull: v })} />
        </div>
        <div className="stat-row" style={{ marginBottom: 0 }}>
          <div className="stat-label"><span className="lbl">Activatie</span><span className="stat-sub">{sq.activated ? "geactiveerd deze ronde" : "nog niet geactiveerd"}</span></div>
          {canFinish ? (
            <button className="btn btn-accent" onClick={() => onFinish(sq.id)} title="Rond deze squadron-activatie af">Klaar ✓</button>
          ) : (
            <button className={"btn " + (sq.activated ? "" : "btn-accent")} onClick={() => onActivate(sq.id)}>{sq.activated ? "Reset" : "Activeer"}</button>
          )}
        </div>
      </div>

      <div className="panel-sec">
        <SecHead>Aanval</SecHead>
        <div className="sec-body" style={{ paddingTop: 4 }}>
          <div className="range-seg" style={{ marginBottom: 10 }}>
            <button data-active={mode === "antiSquad"} onClick={() => { setMode("antiSquad"); setRoll(null); setTargetId(null); }}>vs Squadron</button>
            <button data-active={mode === "antiShip"} onClick={() => { setMode("antiShip"); setRoll(null); setTargetId(null); }}>vs Schip</button>
          </div>
          {mode === "antiShip" && !isBomber ? (
            <div className="mono" style={{ fontSize: 10.5, color: "var(--warn, #d9b24a)", marginBottom: 8 }}>Geen Bomber-keyword — vs schip is normaal niet toegestaan.</div>
          ) : null}
          {blockReason ? (
            <div className="mono" style={{ fontSize: 10.5, color: "var(--bad)", marginBottom: 8 }}>{blockReason.charAt(0).toUpperCase() + blockReason.slice(1)}.</div>
          ) : null}
          <div className="field" style={{ marginBottom: 10 }}>
            <span className="lbl">Doelwit ({mode === "antiSquad" ? "dogfight-bereik" : "close range"})</span>
            {targets.length ? (
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                {targets.map((t) => (
                  <button key={t.id} className="btn btn-ghost" data-active={targetId === t.id}
                          style={{ justifyContent: "flex-start", gap: 7, ...(targetId === t.id ? { borderColor: fc, color: "var(--text)" } : {}) }}
                          onClick={() => { setTargetId(t.id); setRoll(null); }}>
                    <FactionDot faction={t.faction} /> {t.name}
                    <span className="mono" style={{ marginLeft: "auto", fontSize: 10.5, color: "var(--text-faint)" }}>hull {t.hull}</span>
                  </button>
                ))}
              </div>
            ) : !blockReason ? <div className="mono" style={{ fontSize: 11.5, color: "var(--text-faint)" }}>Geen doelen binnen bereik — sleep het squadron dichterbij.</div> : null}
          </div>
          <div className="mono" style={{ fontSize: 11.5, color: "var(--text-dim)", marginBottom: 10 }}>
            Dice: {DICE_ORDER.filter((c) => (mode === "antiSquad" ? sq.antiSquad : sq.antiShip)[c]).map((c) => `${(mode === "antiSquad" ? sq.antiSquad : sq.antiShip)[c]} ${c}`).join(", ") || "geen"}
          </div>
          {attacked ? <div className="mono" style={{ fontSize: 11, color: "var(--text-faint)", marginBottom: 8 }}>Dit squadron heeft deze activatie al aangevallen.</div> : null}
          <button className="btn btn-accent" style={{ width: "100%" }} onClick={doRoll}
                  disabled={attacked || !!blockReason || !target || !myTurn || poolSize(mode === "antiSquad" ? sq.antiSquad : sq.antiShip) === 0}>Rol aanval</button>
          {roll ? (
            <>
              <div className="dice-tray" style={{ marginTop: 10, minHeight: 0 }}>
                {roll.dice.map((d) => <div key={d.id} className="die" data-color={d.color} style={{ width: 38, height: 38 }}><div className="die-face"><FaceGlyph face={d.face} size={20} /></div></div>)}
              </div>
              <div className="ar-tallies" style={{ marginTop: 10 }}>
                <span><b className="mono">{roll.tally.dmg}</b> schade</span>
                <span><b className="mono" style={{ color: "var(--bad)" }}>{roll.tally.crit}</b> crit</span>
                <span><b className="mono" style={{ color: "var(--republic)" }}>{roll.tally.acc}</b> acc</span>
              </div>
              {target ? (
                <button className="btn" style={{ width: "100%", marginTop: 10 }} disabled={roll.applied} onClick={applyRoll}>
                  {roll.applied ? "✓ Schade toegepast" : `Pas ${roll.tally.dmg} schade toe op ${target.name}`}
                </button>
              ) : null}
            </>
          ) : null}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { SquadronToken, SquadronPanel });
