import * as THREE from 'three';
import type { Game } from './Game';
import { Enemy } from './Enemy';

const SHOOT_INTERVAL = 3;
const SHOOT_RANGE = 20;

export class Turret extends Enemy {
  private model: THREE.Group;
  private cap: THREE.Mesh;
  private shootTimer = 1 + Math.random();
  private swayTime = Math.random() * Math.PI * 2;

  constructor() {
    super();
    this.health = 80;
    this.speed = 0;
    this.xp = 25;
    this.contactDps = 0;
    this.immovable = true;

    this.model = new THREE.Group();
    this.fadeOutModel = this.model;
    this.body.add(this.model);

    const stalkMat = new THREE.MeshToonMaterial({ color: 0xe8dcc0 });
    const capMat = new THREE.MeshToonMaterial({ color: 0xcc3344 });
    const spotMat = new THREE.MeshToonMaterial({ color: 0xfff0e0 });

    // Stalk
    const stalk = new THREE.Mesh(new THREE.CylinderGeometry(0.16, 0.28, 0.8, 10), stalkMat);
    stalk.position.y = 0.4;
    stalk.castShadow = true;
    this.registerFadeMesh(stalk);
    this.model.add(stalk);

    // Cap
    this.cap = new THREE.Mesh(new THREE.SphereGeometry(0.5, 18, 14), capMat);
    this.cap.scale.set(1, 0.65, 1);
    this.cap.position.y = 0.9;
    this.cap.castShadow = true;
    this.registerFadeMesh(this.cap);
    this.model.add(this.cap);

    // Spots
    for (const [dx, dz] of [[0, 0], [0.28, 0.12], [-0.26, 0.18], [0.05, -0.3]] as const) {
      const spot = new THREE.Mesh(new THREE.SphereGeometry(0.09, 10, 8), spotMat);
      spot.scale.set(1, 0.45, 1);
      spot.position.set(dx, 1.16, dz);
      this.registerFadeMesh(spot);
      this.model.add(spot);
    }
  }

  playAnim() {
    // Procedural visuals only
  }

  updateAnimation(dt: number) {
    this.updateFadeDeath(dt, { duration: 0.9, sink: 0.3 });
  }

  update(dt: number, game: Game) {
    this.swayTime += dt;

    // Slight sway
    this.model.rotation.z = Math.sin(this.swayTime * 1.5) * 0.06;
    this.cap.rotation.y = this.swayTime * 0.4;

    const playerPos = game.player.body.position;
    const toPlayer = new THREE.Vector3().subVectors(playerPos, this.body.position);
    toPlayer.y = 0;
    const dist = toPlayer.length();

    if (dist > 0.1) {
      this.body.lookAt(
        this.body.position.x + toPlayer.x,
        this.body.position.y,
        this.body.position.z + toPlayer.z
      );
    }

    this.shootTimer -= dt;
    if (dist < SHOOT_RANGE && this.shootTimer <= 0 && game.player.health > 0) {
      this.shootTimer = SHOOT_INTERVAL + Math.random() * 0.5;
      const from = this.body.position.clone();
      from.y += 1.0;
      const target = playerPos.clone();
      target.y += 0.6;
      game.spawnEnemyProjectile(from, target, 15);
    }
  }

  protected onDeath(_game: Game) {
    this.beginFadeDeath();
  }
}
