/* global React, GameEngine */
const VIEW = 900;
const HALF = VIEW / 2;

function hexPoints(r) {
  const pts = [];
  for (let i = 0; i < 6; i++) {
    const a = -Math.PI / 2 + i * Math.PI / 3;
    pts.push(`${(r * Math.cos(a)).toFixed(2)},${(r * Math.sin(a)).toFixed(2)}`);
  }
  return pts.join(" ");
}

// Render the polygon floor (full arena interior)
function ArenaFloor({ sides }) {
  const pts = sides.map(s => `${s.a.x.toFixed(1)},${s.a.y.toFixed(1)}`).join(" ");
  return React.createElement("polygon", {
    points: pts,
    fill: "url(#floor)",
    stroke: "rgba(255,255,255,0.05)",
    strokeWidth: 1,
  });
}

// Render one side: paddle if alive, solid wall if dead
function SideRender({ side, player, paddleFrac, pulse, time }) {
  const meta = GameEngine.PALETTE[side.i];
  // Side line geometry (full segment)
  const ax = side.a.x, ay = side.a.y, bx = side.b.x, by = side.b.y;

  if (!player.alive) {
    // Solid wall — bright stripe in player color, slightly brighter near recently-eliminated
    const sinceOut = player.eliminatedAt != null ? time - player.eliminatedAt : 999;
    const flash = Math.max(0, 1 - sinceOut * 1.2);
    return React.createElement("g", null,
      // Outer thick stroke (the wall)
      React.createElement("line", {
        x1: ax, y1: ay, x2: bx, y2: by,
        stroke: meta.color,
        strokeWidth: 14,
        strokeLinecap: "butt",
        opacity: 0.95,
        filter: "url(#glow)",
      }),
      // Hatching to read as 'solid wall'
      React.createElement("line", {
        x1: ax, y1: ay, x2: bx, y2: by,
        stroke: "rgba(0,0,0,0.55)",
        strokeWidth: 14,
        strokeDasharray: "3 6",
        strokeLinecap: "butt",
      }),
      flash > 0 && React.createElement("line", {
        x1: ax, y1: ay, x2: bx, y2: by,
        stroke: "#FFFFFF",
        strokeWidth: 14 + flash * 16,
        opacity: flash * 0.7,
        filter: "url(#glowStrong)",
      }),
    );
  }

  // Living: thin baseline + paddle
  const half = paddleFrac / 2;
  const t0 = player.paddlePos - half;
  const t1 = player.paddlePos + half;
  const p0 = { x: ax + (bx - ax) * t0, y: ay + (by - ay) * t0 };
  const p1 = { x: ax + (bx - ax) * t1, y: ay + (by - ay) * t1 };

  // Pulse glow when this paddle just hit ball
  const isPulsing = pulse && pulse.side === side.i ? pulse.t : 0;

  return React.createElement("g", null,
    // baseline (the side itself, dim)
    React.createElement("line", {
      x1: ax, y1: ay, x2: bx, y2: by,
      stroke: "rgba(255,255,255,0.1)",
      strokeWidth: 2,
      strokeLinecap: "round",
    }),
    // tick marks at endpoints
    React.createElement("circle", { cx: ax, cy: ay, r: 3, fill: "rgba(255,255,255,0.2)" }),
    React.createElement("circle", { cx: bx, cy: by, r: 3, fill: "rgba(255,255,255,0.2)" }),
    // paddle pulse glow (beneath)
    isPulsing > 0 && React.createElement("line", {
      x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y,
      stroke: meta.glow,
      strokeWidth: 22 + isPulsing * 12,
      strokeLinecap: "round",
      opacity: isPulsing * 0.55,
      filter: "url(#glowStrong)",
    }),
    // paddle main
    React.createElement("line", {
      x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y,
      stroke: meta.color,
      strokeWidth: 12,
      strokeLinecap: "round",
      filter: "url(#glow)",
    }),
    // inner highlight
    React.createElement("line", {
      x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y,
      stroke: meta.glow,
      strokeWidth: 4,
      strokeLinecap: "round",
      opacity: 0.7,
    }),
  );
}

// Seat labels — one per side, just outside the polygon
function SeatLabels({ sides, players, yourSeat, arenaR }) {
  return React.createElement("g", null,
    sides.map((side, i) => {
      const meta = GameEngine.PALETTE[i];
      const p = players[i];
      // outward normal = -inward
      const out = { x: -side.normal.x, y: -side.normal.y };
      const cx = side.mid.x + out.x * 36;
      const cy = side.mid.y + out.y * 36;
      const isYou = i === yourSeat;
      return React.createElement("g", { key: i, opacity: p.alive ? 1 : 0.4 },
        React.createElement("text", {
          x: cx, y: cy,
          textAnchor: "middle",
          dominantBaseline: "middle",
          fill: meta.color,
          fontFamily: "ui-monospace, Menlo, monospace",
          fontSize: 14,
          fontWeight: 700,
          letterSpacing: 2,
          style: { textTransform: "uppercase" },
        }, isYou ? "YOU" : meta.name),
        !p.alive && p.placement && React.createElement("text", {
          x: cx, y: cy + 16,
          textAnchor: "middle",
          fill: "rgba(255,255,255,0.4)",
          fontFamily: "ui-monospace, Menlo, monospace",
          fontSize: 10,
          letterSpacing: 1,
        }, `#${p.placement}`),
      );
    })
  );
}

function Ball({ pos, r, trail, showTrails }) {
  return React.createElement("g", null,
    showTrails && trail.map((pt, idx) => {
      const a = (idx + 1) / trail.length;
      return React.createElement("circle", {
        key: idx,
        cx: pt.x, cy: pt.y,
        r: r * (0.3 + a * 0.7),
        fill: "#FDDA24",
        opacity: a * 0.35,
      });
    }),
    // outer glow
    React.createElement("circle", {
      cx: pos.x, cy: pos.y, r: r * 2.4,
      fill: "#FDDA24",
      opacity: 0.18,
      filter: "url(#glowStrong)",
    }),
    React.createElement("circle", {
      cx: pos.x, cy: pos.y, r: r,
      fill: "url(#ballGrad)",
      filter: "url(#glow)",
    }),
    React.createElement("circle", {
      cx: pos.x - r * 0.3, cy: pos.y - r * 0.3, r: r * 0.4,
      fill: "rgba(255,255,255,0.85)",
    }),
  );
}

// Spark events (paddle hits, eliminations)
function Sparks({ events, time }) {
  return React.createElement("g", null,
    events.map((e, i) => {
      const age = time - e.t;
      const life = e.kind === "out" ? 0.6 : 0.35;
      const a = Math.max(0, 1 - age / life);
      if (a <= 0) return null;
      const r = e.kind === "out" ? 60 * (1 - a * 0.3) : 22 * (1 - a * 0.5);
      const meta = GameEngine.PALETTE[e.seat];
      return React.createElement("circle", {
        key: i,
        cx: e.pos.x, cy: e.pos.y,
        r,
        fill: "none",
        stroke: e.kind === "out" ? "#FFFFFF" : meta.glow,
        strokeWidth: e.kind === "out" ? 3 : 2,
        opacity: a,
        filter: "url(#glow)",
      });
    })
  );
}

function Arena({ game, svgRef, trail, showTrails }) {
  if (!game) {
    return React.createElement("div", { className: "arena" },
      React.createElement("svg", {
        viewBox: `-${HALF} -${HALF} ${VIEW} ${VIEW}`,
        ref: svgRef,
      })
    );
  }

  // Storm zone: starting polygon (full size) MINUS current arena = poison ring.
  // Outer matches the original arena exactly so there's NO storm at t=0.
  const stormOuter = GameEngine.buildPolygon(game.n, game.opts.arenaR);
  const stormInner = game.sides.map(s => s.a); // current live polygon vertices (CW)
  const stormPath =
    "M " + stormOuter.map(v => `${v.x.toFixed(1)} ${v.y.toFixed(1)}`).join(" L ") + " Z " +
    "M " + stormInner.map(v => `${v.x.toFixed(1)} ${v.y.toFixed(1)}`).join(" L ") + " Z";
  const arenaShrink = 1 - (game.arenaR / game.opts.arenaR); // 0..~0.5
  // 0..1 ramp; storm only becomes visible after the arena actually starts closing
  const stormIntensity = Math.min(1, Math.max(0, arenaShrink) * 2.2);
  const stormPulse = 0.55 + 0.25 * Math.sin(game.time * 2.4);

  // Center mark
  return React.createElement("div", { className: "arena" },
    React.createElement("svg", {
      viewBox: `-${HALF} -${HALF} ${VIEW} ${VIEW}`,
      ref: svgRef,
    },
      React.createElement("defs", null,
        React.createElement("radialGradient", { id: "floor", cx: "50%", cy: "50%", r: "60%" },
          React.createElement("stop", { offset: "0%", stopColor: "#191923" }),
          React.createElement("stop", { offset: "70%", stopColor: "#0E0E16" }),
          React.createElement("stop", { offset: "100%", stopColor: "#08080C" }),
        ),
        React.createElement("radialGradient", { id: "ballGrad", cx: "50%", cy: "50%", r: "50%" },
          React.createElement("stop", { offset: "0%", stopColor: "#FFFFFF" }),
          React.createElement("stop", { offset: "45%", stopColor: "#FFE85C" }),
          React.createElement("stop", { offset: "100%", stopColor: "#FDDA24" }),
        ),
        React.createElement("filter", { id: "glow", x: "-50%", y: "-50%", width: "200%", height: "200%" },
          React.createElement("feGaussianBlur", { stdDeviation: 3, result: "blur" }),
          React.createElement("feMerge", null,
            React.createElement("feMergeNode", { in: "blur" }),
            React.createElement("feMergeNode", { in: "SourceGraphic" }),
          )
        ),
        React.createElement("filter", { id: "glowStrong", x: "-50%", y: "-50%", width: "200%", height: "200%" },
          React.createElement("feGaussianBlur", { stdDeviation: 7, result: "blur" }),
          React.createElement("feMerge", null,
            React.createElement("feMergeNode", { in: "blur" }),
            React.createElement("feMergeNode", { in: "blur" }),
            React.createElement("feMergeNode", { in: "SourceGraphic" }),
          )
        ),
        // Storm: muted purple radial gradient — readable but not drowning
        React.createElement("radialGradient", { id: "stormGrad", cx: "50%", cy: "50%", r: "70%" },
          React.createElement("stop", { offset: "0%", stopColor: "#6B4A9E", stopOpacity: 0.10 }),
          React.createElement("stop", { offset: "70%", stopColor: "#4A2D7A", stopOpacity: 0.28 }),
          React.createElement("stop", { offset: "100%", stopColor: "#2A1547", stopOpacity: 0.42 }),
        ),
        // Diagonal hatch overlay — subtle
        React.createElement("pattern", {
          id: "stormHatch",
          patternUnits: "userSpaceOnUse",
          width: 16, height: 16,
          patternTransform: "rotate(45)",
        },
          React.createElement("rect", { width: 16, height: 16, fill: "transparent" }),
          React.createElement("line", {
            x1: 0, y1: 0, x2: 0, y2: 16,
            stroke: "#A78BD9", strokeWidth: 1, opacity: 0.22,
          }),
        ),
        // Soft inner edge gradient — "warning band" between live arena and storm
        React.createElement("radialGradient", { id: "edgeWarn", cx: "50%", cy: "50%", r: "50%" },
          React.createElement("stop", { offset: "85%", stopColor: "#9B5BFF", stopOpacity: 0 }),
          React.createElement("stop", { offset: "100%", stopColor: "#E879F9", stopOpacity: 0.7 }),
        ),
      ),

      // ====== STORM (poison closing zone) ======
      // Only render once the arena has actually started shrinking
      stormIntensity > 0.01 && React.createElement(React.Fragment, null,
        React.createElement("path", {
          d: stormPath,
          fill: "url(#stormGrad)",
          fillRule: "evenodd",
          opacity: 0.4 + stormIntensity * 0.35,
        }),
        React.createElement("path", {
          d: stormPath,
          fill: "url(#stormHatch)",
          fillRule: "evenodd",
          opacity: 0.3 + stormIntensity * 0.3,
        }),
        React.createElement("polygon", {
          points: stormInner.map(v => `${v.x.toFixed(1)},${v.y.toFixed(1)}`).join(" "),
          fill: "none",
          stroke: "#A78BD9",
          strokeWidth: 1.5,
          opacity: (0.3 + 0.25 * stormPulse) * (0.4 + stormIntensity * 0.6),
          filter: "url(#glow)",
        }),
      ),

      // Floor (live arena interior)
      React.createElement(ArenaFloor, { sides: game.sides }),

      // Center crosshair
      React.createElement("g", { opacity: 0.18, stroke: "rgba(255,255,255,0.4)", strokeWidth: 1 },
        React.createElement("line", { x1: -8, y1: 0, x2: 8, y2: 0 }),
        React.createElement("line", { x1: 0, y1: -8, x2: 0, y2: 8 }),
      ),

      // Sparks (under sides so they read at edges)
      React.createElement(Sparks, { events: game.events, time: game.time }),

      // Each side
      game.sides.map((side, i) =>
        React.createElement(SideRender, {
          key: i,
          side,
          player: game.players[i],
          paddleFrac: game.paddleFrac,
          pulse: game.pulse,
          time: game.time,
        })
      ),

      // Seat labels (outside arena)
      React.createElement(SeatLabels, {
        sides: game.sides,
        players: game.players,
        yourSeat: game.yourSeat,
        arenaR: game.arenaR,
      }),

      // Ball
      React.createElement(Ball, {
        pos: game.ball.pos,
        r: game.ballR,
        trail,
        showTrails,
      }),

      // Global flash overlay on elimination
      game.flash > 0 && React.createElement("circle", {
        cx: 0, cy: 0, r: HALF * 1.4,
        fill: "white",
        opacity: game.flash * 0.12,
      }),
    )
  );
}

window.HexRoyaleArena = Arena;
window.HexRoyaleViewSize = VIEW;
