import { Application, Graphics, Text, TextStyle, Container } from "pixi.js";
import { GlowFilter } from "pixi-filters";
import { CANVAS_WIDTH, CANVAS_HEIGHT } from "./game.config";

// ─── Constants ───────────────────────────────────────────────────────────────
const COLORS = {
  bg: 0x000010,
  playerFill: 0x00ffff,
  playerGlow: 0x00ffff,
  laserPlayer: 0x00ffff,
  laserEnemy: 0xff1b6d,
  enemyA: 0xff1b6d,
  enemyB: 0xffd700,
  enemyC: 0x8b5cf6,
  gold: 0xffd700,
  starDim: 0x334466,
  starBright: 0xaaccff,
  life: 0xff1b6d,
  explosion: [0xff6600, 0xffd700, 0xff1b6d, 0xffffff] as number[],
};

const PLAYER_SPEED = 340;
const PLAYER_W = 36;
const PLAYER_H = 28;
const LASER_SPEED = 600;
const SHOOT_COOLDOWN = 0.18; // seconds
const ENEMY_LASER_SPEED = 280;
const INVINCIBLE_DURATION = 2.0; // seconds after being hit

// ─── Text styles (created once) ──────────────────────────────────────────────
const STYLE_SCORE = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 22,
  fill: COLORS.gold,
  letterSpacing: 2,
  dropShadow: { alpha: 0.9, angle: 0, blur: 12, color: COLORS.gold, distance: 0 },
});
const STYLE_WAVE = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 22,
  fill: COLORS.playerFill,
  letterSpacing: 2,
  dropShadow: { alpha: 0.9, angle: 0, blur: 12, color: COLORS.playerFill, distance: 0 },
});
const STYLE_TITLE = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 52,
  fill: 0x00ffff,
  letterSpacing: 4,
  dropShadow: { alpha: 1, angle: 0, blur: 24, color: 0x00ffff, distance: 0 },
});
const STYLE_SUBTITLE = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 20,
  fill: 0xffffff,
  letterSpacing: 2,
  dropShadow: { alpha: 0.7, angle: 0, blur: 8, color: 0x8888ff, distance: 0 },
});
const STYLE_GAMEOVER = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 56,
  fill: 0xff1b6d,
  letterSpacing: 4,
  dropShadow: { alpha: 1, angle: 0, blur: 28, color: 0xff1b6d, distance: 0 },
});
const STYLE_SMALL = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 18,
  fill: 0xffd700,
  letterSpacing: 2,
});
const STYLE_HIGHSCORE = new TextStyle({
  fontFamily: "Russo One",
  fontSize: 20,
  fill: 0xffd700,
  letterSpacing: 2,
  dropShadow: { alpha: 0.8, angle: 0, blur: 10, color: 0xffd700, distance: 0 },
});

// ─── Types ────────────────────────────────────────────────────────────────────
type GameState = "menu" | "playing" | "gameover" | "wave_announce";

interface Star {
  gfx: Graphics;
  speed: number;
  baseAlpha: number;
  twinkleOffset: number;
}

interface Laser {
  gfx: Graphics;
  vy: number;
  vx: number;
}

interface Enemy {
  gfx: Graphics;
  type: 0 | 1 | 2; // 0=drone, 1=zigzag, 2=elite
  hp: number;
  maxHp: number;
  baseX: number;
  baseY: number;
  t: number; // phase timer
  row: number;
  col: number;
  shootTimer: number;
  shootInterval: number;
  points: number;
}

interface Particle {
  gfx: Graphics;
  vx: number;
  vy: number;
  life: number;
  maxLife: number;
  color: number;
}

// ─── App ─────────────────────────────────────────────────────────────────────
const app = new Application();

async function init() {
  await app.init({
    width: CANVAS_WIDTH,
    height: CANVAS_HEIGHT,
    backgroundColor: COLORS.bg,
    antialias: true,
  });
  document.body.appendChild(app.canvas);

  // ── Layers
  const starContainer = new Container();
  const gameContainer = new Container();
  const uiContainer = new Container();
  const overlayContainer = new Container();
  app.stage.addChild(starContainer);
  app.stage.addChild(gameContainer);
  app.stage.addChild(uiContainer);
  app.stage.addChild(overlayContainer);

  // ── Stars
  const stars: Star[] = [];
  for (let i = 0; i < 160; i++) {
    const bright = Math.random() > 0.6;
    const size = bright ? Math.random() * 2.2 + 0.8 : Math.random() * 1.2 + 0.3;
    const speed = bright ? Math.random() * 40 + 20 : Math.random() * 20 + 8;
    const g = new Graphics();
    g.circle(0, 0, size);
    g.fill(bright ? COLORS.starBright : COLORS.starDim);
    g.x = Math.random() * CANVAS_WIDTH;
    g.y = Math.random() * CANVAS_HEIGHT;
    const baseAlpha = Math.random() * 0.6 + 0.3;
    g.alpha = baseAlpha;
    starContainer.addChild(g);
    stars.push({ gfx: g, speed, baseAlpha, twinkleOffset: Math.random() * Math.PI * 2 });
  }

  // ── Player ship
  const playerGfx = new Graphics();
  drawPlayerShip(playerGfx);
  playerGfx.x = CANVAS_WIDTH / 2;
  playerGfx.y = CANVAS_HEIGHT - 54;
  const playerGlow = new GlowFilter({ distance: 18, outerStrength: 2.5, color: COLORS.playerGlow, quality: 0.4 });
  playerGfx.filters = [playerGlow];
  gameContainer.addChild(playerGfx);

  // ── Lives display
  const livesContainer = new Container();
  livesContainer.x = CANVAS_WIDTH - 130;
  livesContainer.y = 14;
  uiContainer.addChild(livesContainer);
  const livesLabel = new Text({ text: "LIVES", style: STYLE_SMALL });
  livesLabel.x = 0;
  livesLabel.y = 0;
  livesContainer.addChild(livesLabel);

  // ── Score / Wave text
  const scoreText = new Text({ text: "SCORE: 0", style: STYLE_SCORE });
  scoreText.x = 16;
  scoreText.y = 14;
  uiContainer.addChild(scoreText);

  const waveText = new Text({ text: "WAVE 1", style: STYLE_WAVE });
  waveText.x = CANVAS_WIDTH / 2;
  waveText.y = 14;
  uiContainer.addChild(waveText);

  const highScoreText = new Text({ text: "BEST: 0", style: STYLE_HIGHSCORE });
  highScoreText.x = 16;
  highScoreText.y = 42;
  uiContainer.addChild(highScoreText);

  // ── Overlay elements
  let overlayActive = false;
  const overlayBg = new Graphics();
  overlayBg.rect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
  overlayBg.fill({ color: 0x000010, alpha: 0.78 });
  overlayContainer.addChild(overlayBg);

  const titleText = new Text({ text: "VOID STRIKE", style: STYLE_TITLE });
  titleText.anchor.set(0.5);
  titleText.x = CANVAS_WIDTH / 2;
  titleText.y = CANVAS_HEIGHT / 2 - 90;
  overlayContainer.addChild(titleText);

  const subtitleText = new Text({ text: "PRESS SPACE OR CLICK TO START", style: STYLE_SUBTITLE });
  subtitleText.anchor.set(0.5);
  subtitleText.x = CANVAS_WIDTH / 2;
  subtitleText.y = CANVAS_HEIGHT / 2 + 10;
  overlayContainer.addChild(subtitleText);

  const gameOverText = new Text({ text: "GAME OVER", style: STYLE_GAMEOVER });
  gameOverText.anchor.set(0.5);
  gameOverText.x = CANVAS_WIDTH / 2;
  gameOverText.y = CANVAS_HEIGHT / 2 - 90;
  overlayContainer.addChild(gameOverText);
  gameOverText.visible = false;

  const finalScoreText = new Text({ text: "", style: STYLE_SUBTITLE });
  finalScoreText.anchor.set(0.5);
  finalScoreText.x = CANVAS_WIDTH / 2;
  finalScoreText.y = CANVAS_HEIGHT / 2 - 20;
  overlayContainer.addChild(finalScoreText);

  const waveAnnounceText = new Text({ text: "", style: STYLE_TITLE });
  waveAnnounceText.anchor.set(0.5);
  waveAnnounceText.x = CANVAS_WIDTH / 2;
  waveAnnounceText.y = CANVAS_HEIGHT / 2 - 30;
  waveAnnounceText.visible = false;
  overlayContainer.addChild(waveAnnounceText);

  // ── Game state variables
  let state: GameState = "menu";
  let score = 0;
  let highScore = 0;
  let lives = 3;
  let wave = 0;
  let shootTimer = 0;
  let invincibleTimer = 0;
  let waveAnnounceTimer = 0;
  let time = 0;
  let playerAlive = true;

  const keys: Record<string, boolean> = {};
  const playerLasers: Laser[] = [];
  const enemyLasers: Laser[] = [];
  const enemies: Enemy[] = [];
  const particles: Particle[] = [];

  let lifeIcons: Graphics[] = [];

  // ── Input
  window.addEventListener("keydown", (e) => {
    keys[e.key] = true;
    if ((e.key === " " || e.key === "Enter") && (state === "menu" || state === "gameover")) {
      startGame();
    }
    e.preventDefault();
  });
  window.addEventListener("keyup", (e) => { keys[e.key] = false; });

  app.stage.interactive = true;
  app.stage.on("pointerdown", () => {
    if (state === "menu" || state === "gameover") startGame();
  });

  // ── Helper: draw life hearts
  function rebuildLivesUI() {
    lifeIcons.forEach(ic => { livesContainer.removeChild(ic); ic.destroy(); });
    lifeIcons = [];
    for (let i = 0; i < lives; i++) {
      const ic = new Graphics();
      drawMiniShip(ic);
      ic.x = 28 + i * 26;
      ic.y = 20;
      ic.filters = [new GlowFilter({ distance: 8, outerStrength: 1.5, color: COLORS.life, quality: 0.4 })];
      livesContainer.addChild(ic);
      lifeIcons.push(ic);
    }
  }

  // ── Start / reset game
  function startGame() {
    score = 0;
    lives = 3;
    wave = 0;
    playerAlive = true;
    invincibleTimer = 0;
    shootTimer = 0;

    // Clear arrays
    clearArray(playerLasers, gameContainer);
    clearArray(enemyLasers, gameContainer);
    clearEnemies();
    clearParticles();

    playerGfx.x = CANVAS_WIDTH / 2;
    playerGfx.y = CANVAS_HEIGHT - 54;
    playerGfx.alpha = 1;
    playerGfx.visible = true;

    rebuildLivesUI();
    showOverlay(false);
    nextWave();
  }

  function nextWave() {
    wave++;
    state = "wave_announce";
    waveAnnounceTimer = 1.8;
    titleText.visible = false;
    gameOverText.visible = false;
    waveAnnounceText.visible = true;
    waveAnnounceText.text = `WAVE  ${wave}`;
    overlayBg.visible = true;
    subtitleText.visible = false;
    overlayActive = true;
  }

  function spawnWave() {
    clearEnemies();
    const difficulty = 1 + (wave - 1) * 0.22;
    // Rows/cols scale with wave
    const cols = Math.min(3 + wave, 9);
    const rows = Math.min(1 + Math.floor(wave / 2), 4);
    const spacing = Math.min(CANVAS_WIDTH / (cols + 1), 88);
    const startX = (CANVAS_WIDTH - spacing * (cols - 1)) / 2;

    for (let r = 0; r < rows; r++) {
      for (let c = 0; c < cols; c++) {
        let type: 0 | 1 | 2 = 0;
        if (wave >= 3 && r === 0 && c % 3 === 0) type = 2; // elite
        else if (wave >= 2 && c % 2 === 1) type = 1; // zigzag

        const hp = type === 2 ? 3 : 1;
        const points = type === 2 ? 50 : type === 1 ? 20 : 10;
        const shootInterval = (type === 2 ? 1.8 : type === 1 ? 2.4 : 3.2) / difficulty;

        const g = new Graphics();
        drawEnemy(g, type, hp, hp);
        const bx = startX + c * spacing;
        const by = 80 + r * 64;
        g.x = bx;
        g.y = by;
        const glow = new GlowFilter({
          distance: 14,
          outerStrength: type === 2 ? 2.5 : 1.6,
          color: type === 2 ? COLORS.enemyC : type === 1 ? COLORS.enemyB : COLORS.enemyA,
          quality: 0.4,
        });
        g.filters = [glow];
        gameContainer.addChild(g);

        enemies.push({
          gfx: g, type, hp, maxHp: hp,
          baseX: bx, baseY: by,
          t: (r * cols + c) * 0.18,
          row: r, col: c,
          shootTimer: Math.random() * shootInterval,
          shootInterval,
          points,
        });
      }
    }
  }

  function showOverlay(show: boolean) {
    overlayActive = show;
    overlayBg.visible = show;
    subtitleText.visible = false;
    titleText.visible = false;
    gameOverText.visible = false;
    waveAnnounceText.visible = false;
    finalScoreText.visible = false;
  }

  function showMenu() {
    state = "menu";
    overlayActive = true;
    overlayBg.visible = true;
    titleText.visible = true;
    titleText.text = "VOID STRIKE";
    subtitleText.text = "PRESS SPACE OR CLICK TO START";
    subtitleText.visible = true;
    gameOverText.visible = false;
    waveAnnounceText.visible = false;
    finalScoreText.visible = false;
  }

  function showGameOver() {
    state = "gameover";
    overlayActive = true;
    overlayBg.visible = true;
    gameOverText.visible = true;
    finalScoreText.text = `SCORE: ${score}    WAVE: ${wave}`;
    finalScoreText.visible = true;
    subtitleText.text = "PRESS SPACE OR CLICK TO RETRY";
    subtitleText.visible = true;
    titleText.visible = false;
    waveAnnounceText.visible = false;
  }

  // Initial menu
  showMenu();

  // ── Spawn player laser
  function shootPlayerLaser() {
    const g = new Graphics();
    g.rect(-2, -14, 4, 14);
    g.fill(COLORS.laserPlayer);
    g.x = playerGfx.x;
    g.y = playerGfx.y - 18;
    g.filters = [new GlowFilter({ distance: 10, outerStrength: 2.5, color: COLORS.laserPlayer, quality: 0.3 })];
    gameContainer.addChild(g);
    playerLasers.push({ gfx: g, vy: -LASER_SPEED, vx: 0 });
  }

  // ── Spawn enemy laser
  function shootEnemyLaser(enemy: Enemy) {
    const g = new Graphics();
    g.rect(-2, 0, 4, 12);
    g.fill(COLORS.laserEnemy);
    g.x = enemy.gfx.x;
    g.y = enemy.gfx.y + 16;
    g.filters = [new GlowFilter({ distance: 8, outerStrength: 2, color: COLORS.laserEnemy, quality: 0.3 })];
    gameContainer.addChild(g);
    // Slight aim toward player
    const dx = playerGfx.x - enemy.gfx.x;
    const dy = playerGfx.y - enemy.gfx.y;
    const len = Math.sqrt(dx * dx + dy * dy);
    enemyLasers.push({ gfx: g, vy: ENEMY_LASER_SPEED * (dy / len), vx: ENEMY_LASER_SPEED * (dx / len) * 0.4 });
  }

  // ── Explosion particles
  function spawnExplosion(x: number, y: number, count: number = 18, big = false) {
    for (let i = 0; i < count; i++) {
      const color = COLORS.explosion[Math.floor(Math.random() * COLORS.explosion.length)];
      const size = big ? Math.random() * 6 + 3 : Math.random() * 4 + 2;
      const g = new Graphics();
      g.rect(-size / 2, -size / 2, size, size);
      g.fill(color);
      g.x = x;
      g.y = y;
      g.filters = [new GlowFilter({ distance: 8, outerStrength: 2, color, quality: 0.3 })];
      const angle = Math.random() * Math.PI * 2;
      const spd = big ? Math.random() * 180 + 60 : Math.random() * 140 + 40;
      gameContainer.addChild(g);
      particles.push({
        gfx: g, color,
        vx: Math.cos(angle) * spd,
        vy: Math.sin(angle) * spd,
        life: 0.55 + Math.random() * 0.35,
        maxLife: 0.55 + Math.random() * 0.35,
      });
    }
  }

  // ── Shake
  function shake(intensity: number, duration: number = 120) {
    const ox = app.stage.x, oy = app.stage.y;
    const t0 = Date.now();
    const loop = () => {
      const el = Date.now() - t0;
      if (el < duration) {
        app.stage.x = ox + (Math.random() - 0.5) * intensity * 2;
        app.stage.y = oy + (Math.random() - 0.5) * intensity * 2;
        requestAnimationFrame(loop);
      } else { app.stage.x = ox; app.stage.y = oy; }
    };
    loop();
  }

  // ── AABB collision (centered)
  function hitTest(ax: number, ay: number, aw: number, ah: number,
                   bx: number, by: number, bw: number, bh: number): boolean {
    return Math.abs(ax - bx) < (aw + bw) / 2 &&
           Math.abs(ay - by) < (ah + bh) / 2;
  }

  // ── Game loop
  app.ticker.add((ticker) => {
    const dt = ticker.deltaTime / 60;
    time += dt;

    // ── Scrolling stars
    for (const s of stars) {
      s.gfx.y += s.speed * dt;
      if (s.gfx.y > CANVAS_HEIGHT + 4) s.gfx.y = -4;
      s.gfx.alpha = s.baseAlpha + Math.sin(time * 1.8 + s.twinkleOffset) * 0.2;
    }

    if (state === "menu" || state === "gameover") {
      // Animate title pulse
      titleText.scale.set(1 + Math.sin(time * 2.2) * 0.03);
      return;
    }

    if (state === "wave_announce") {
      waveAnnounceTimer -= dt;
      waveAnnounceText.scale.set(1 + Math.sin(time * 4) * 0.04);
      if (waveAnnounceTimer <= 0) {
        showOverlay(false);
        state = "playing";
        spawnWave();
      }
      return;
    }

    // ── PLAYING ──────────────────────────────────────────────────────────────
    shootTimer -= dt;
    invincibleTimer = Math.max(0, invincibleTimer - dt);

    // Player flicker when invincible
    if (invincibleTimer > 0) {
      playerGfx.alpha = Math.sin(time * 28) > 0 ? 1 : 0.25;
    } else {
      playerGfx.alpha = 1;
    }

    // Player glow pulse
    (playerGfx.filters![0] as GlowFilter).outerStrength = 2.5 + Math.sin(time * 3) * 0.8;

    // ── Player movement
    let dx = 0;
    if (keys["ArrowLeft"] || keys["a"] || keys["A"]) dx -= 1;
    if (keys["ArrowRight"] || keys["d"] || keys["D"]) dx += 1;
    playerGfx.x += dx * PLAYER_SPEED * dt;
    playerGfx.x = Math.max(PLAYER_W / 2 + 4, Math.min(CANVAS_WIDTH - PLAYER_W / 2 - 4, playerGfx.x));

    // Slight tilt on movement
    playerGfx.rotation = dx * 0.18;

    // ── Shooting
    if ((keys[" "] || keys["z"] || keys["Z"]) && shootTimer <= 0) {
      shootPlayerLaser();
      shootTimer = SHOOT_COOLDOWN;
    }

    // ── Enemy wave motion & shooting
    const difficulty = 1 + (wave - 1) * 0.22;
    const waveSpeed = 28 + wave * 5;
    const amplitude = 42 + wave * 4;

    for (let i = enemies.length - 1; i >= 0; i--) {
      const e = enemies[i];
      e.t += dt;

      if (e.type === 0) {
        // Drone: gentle sine drift + slow descend
        e.gfx.x = e.baseX + Math.sin(e.t * 1.1 + e.col * 0.7) * amplitude;
        e.baseY += (10 + wave * 1.5) * dt;
        e.gfx.y = e.baseY + Math.cos(e.t * 0.6) * 8;
      } else if (e.type === 1) {
        // Zigzag: faster lateral oscillation
        e.gfx.x = e.baseX + Math.sin(e.t * 2.4 + e.col * 1.2) * (amplitude * 1.3);
        e.baseY += (14 + wave * 2) * dt;
        e.gfx.y = e.baseY;
      } else {
        // Elite: slower but descends more aggressively
        e.gfx.x = e.baseX + Math.sin(e.t * 0.8 + e.col * 0.5) * (amplitude * 0.7);
        e.baseY += (8 + wave * 1.2) * dt;
        e.gfx.y = e.baseY + Math.sin(e.t * 1.4) * 14;
      }

      // Clamp to screen horizontally
      e.gfx.x = Math.max(20, Math.min(CANVAS_WIDTH - 20, e.gfx.x));

      // Enemy rotation wobble
      e.gfx.rotation = Math.sin(e.t * 1.5) * 0.12;

      // Enemy reached bottom => lose life
      if (e.gfx.y > CANVAS_HEIGHT + 10) {
        removeEnemy(i, gameContainer);
        if (invincibleTimer <= 0) takeDamage();
        continue;
      }

      // Enemy shooting
      e.shootTimer -= dt;
      if (e.shootTimer <= 0 && e.gfx.y < CANVAS_HEIGHT - 40 && playerAlive) {
        shootEnemyLaser(e);
        e.shootTimer = e.shootInterval * (0.8 + Math.random() * 0.4);
      }
    }

    // ── Move player lasers
    for (let i = playerLasers.length - 1; i >= 0; i--) {
      const l = playerLasers[i];
      l.gfx.y += l.vy * dt;
      if (l.gfx.y < -20) {
        destroyLaser(playerLasers, i, gameContainer);
        continue;
      }
      // Hit enemies
      let hit = false;
      for (let j = enemies.length - 1; j >= 0; j--) {
        const e = enemies[j];
        if (hitTest(l.gfx.x, l.gfx.y, 4, 14, e.gfx.x, e.gfx.y, 28, 20)) {
          e.hp--;
          spawnExplosion(l.gfx.x, l.gfx.y, 6);
          destroyLaser(playerLasers, i, gameContainer);
          hit = true;
          if (e.hp <= 0) {
            spawnExplosion(e.gfx.x, e.gfx.y, e.type === 2 ? 28 : 18, e.type === 2);
            shake(e.type === 2 ? 10 : 5, e.type === 2 ? 180 : 100);
            score += e.points;
            scoreText.text = `SCORE: ${score}`;
            removeEnemy(j, gameContainer);
          } else {
            // Redraw enemy to show damage
            e.gfx.clear();
            drawEnemy(e.gfx, e.type, e.hp, e.maxHp);
          }
          break;
        }
      }
      if (hit) continue;
    }

    // ── Move enemy lasers
    for (let i = enemyLasers.length - 1; i >= 0; i--) {
      const l = enemyLasers[i];
      l.gfx.x += l.vx * dt;
      l.gfx.y += l.vy * dt;
      if (l.gfx.y > CANVAS_HEIGHT + 20 || l.gfx.x < -20 || l.gfx.x > CANVAS_WIDTH + 20) {
        destroyLaser(enemyLasers, i, gameContainer);
        continue;
      }
      // Hit player
      if (playerAlive && invincibleTimer <= 0 &&
          hitTest(l.gfx.x, l.gfx.y, 4, 12, playerGfx.x, playerGfx.y, PLAYER_W - 4, PLAYER_H - 4)) {
        destroyLaser(enemyLasers, i, gameContainer);
        takeDamage();
      }
    }

    // ── Update particles
    for (let i = particles.length - 1; i >= 0; i--) {
      const p = particles[i];
      p.life -= dt;
      if (p.life <= 0) {
        gameContainer.removeChild(p.gfx);
        p.gfx.destroy();
        particles.splice(i, 1);
        continue;
      }
      p.gfx.x += p.vx * dt;
      p.gfx.y += p.vy * dt;
      p.vy += 80 * dt; // gravity
      const ratio = p.life / p.maxLife;
      p.gfx.alpha = ratio;
      p.gfx.scale.set(ratio * 0.9 + 0.1);
    }

    // ── Check wave cleared
    if (enemies.length === 0 && state === "playing") {
      nextWave();
    }

    // ── Update UI
    waveText.text = `WAVE ${wave}`;
    waveText.x = CANVAS_WIDTH / 2 - waveText.width / 2;
    if (score > highScore) {
      highScore = score;
      highScoreText.text = `BEST: ${highScore}`;
    }
  });

  // ── Take damage
  function takeDamage() {
    if (!playerAlive || invincibleTimer > 0) return;
    lives--;
    shake(12, 200);
    spawnExplosion(playerGfx.x, playerGfx.y, 22, false);
    rebuildLivesUI();
    invincibleTimer = INVINCIBLE_DURATION;

    if (lives <= 0) {
      playerAlive = false;
      playerGfx.visible = false;
      spawnExplosion(playerGfx.x, playerGfx.y, 40, true);
      shake(20, 400);
      setTimeout(() => showGameOver(), 1200);
    }
  }

  // ── Helpers
  function clearArray(arr: Laser[], container: Container) {
    for (const l of arr) { container.removeChild(l.gfx); l.gfx.destroy(); }
    arr.length = 0;
  }
  function clearEnemies() {
    for (const e of enemies) { gameContainer.removeChild(e.gfx); e.gfx.destroy(); }
    enemies.length = 0;
  }
  function clearParticles() {
    for (const p of particles) { gameContainer.removeChild(p.gfx); p.gfx.destroy(); }
    particles.length = 0;
  }
  function removeEnemy(i: number, container: Container) {
    container.removeChild(enemies[i].gfx);
    enemies[i].gfx.destroy();
    enemies.splice(i, 1);
  }
  function destroyLaser(arr: Laser[], i: number, container: Container) {
    container.removeChild(arr[i].gfx);
    arr[i].gfx.destroy();
    arr.splice(i, 1);
  }
}

// ─── Drawing helpers ─────────────────────────────────────────────────────────
function drawPlayerShip(g: Graphics) {
  // Body
  g.poly([
    0, -22,        // nose
    -10, -4,
    -16, 8,
    -8, 4,
    0, 10,
    8, 4,
    16, 8,
    10, -4,
  ]);
  g.fill(0x00ddee);
  // Cockpit
  g.ellipse(0, -6, 6, 8);
  g.fill(0x001833);
  // Wing accents
  g.rect(-18, 4, 6, 4);
  g.fill(0xff1b6d);
  g.rect(12, 4, 6, 4);
  g.fill(0xff1b6d);
  // Engine glow dots
  g.circle(-5, 10, 3);
  g.fill(0xff6600);
  g.circle(5, 10, 3);
  g.fill(0xff6600);
}

function drawMiniShip(g: Graphics) {
  g.poly([0, -9, -6, 4, 6, 4]);
  g.fill(0x00ddee);
  g.rect(-7, 4, 4, 3);
  g.fill(0xff1b6d);
  g.rect(3, 4, 4, 3);
  g.fill(0xff1b6d);
}

function drawEnemy(g: Graphics, type: 0 | 1 | 2, hp: number, maxHp: number) {
  const damaged = hp < maxHp;
  if (type === 0) {
    // Drone: diamond + small wings
    g.poly([0, -14, 12, 0, 0, 14, -12, 0]);
    g.fill(damaged ? 0xaa1144 : 0xff1b6d);
    g.circle(0, 0, 5);
    g.fill(damaged ? 0x440011 : 0xff88bb);
  } else if (type === 1) {
    // Zigzagger: arrowhead
    g.poly([0, -14, 14, 8, 6, 4, 0, 14, -6, 4, -14, 8]);
    g.fill(damaged ? 0xaa8800 : 0xffd700);
    g.rect(-4, -4, 8, 8);
    g.fill(damaged ? 0x554400 : 0xffee88);
  } else {
    // Elite: hexagon + core
    g.poly([0, -16, 14, -8, 14, 8, 0, 16, -14, 8, -14, -8]);
    g.fill(damaged ? 0x440088 : 0x8b5cf6);
    g.poly([0, -8, 7, -4, 7, 4, 0, 8, -7, 4, -7, -4]);
    g.fill(damaged ? 0x220044 : 0xcc99ff);
    g.circle(0, 0, 3);
    g.fill(0xffffff);
  }
}

// Start
document.fonts.ready.then(() => { init(); });
