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

export class Brute extends Enemy {
  protected model: THREE.Group;
  protected legL!: THREE.Group;
  protected legR!: THREE.Group;
  protected armL: THREE.Group | null = null;
  protected armR: THREE.Group | null = null;
  private stepTime = 0;
  private walkAmp = 0;

  constructor() {
    super();
    this.health = 300;
    this.speed = 3.5;
    this.xp = 40;
    this.contactDps = 40;
    this.contactRadius = 2.4;

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

    const rockMat = new THREE.MeshToonMaterial({ color: 0x6a6a78 });
    const darkMat = new THREE.MeshToonMaterial({ color: 0x3c3c46 });

    // Becken + Torso
    const pelvis = new THREE.Mesh(new THREE.BoxGeometry(0.7, 0.35, 0.55), darkMat);
    pelvis.position.y = 0.62;
    this.registerFadeMesh(pelvis);
    this.model.add(pelvis);
    const torso = new THREE.Mesh(new THREE.BoxGeometry(1.3, 1.2, 0.95), rockMat);
    torso.position.y = 0.95;
    torso.castShadow = true;
    this.registerFadeMesh(torso);
    this.model.add(torso);

    // Shoulders
    for (const side of [-1, 1]) {
      const shoulder = new THREE.Mesh(new THREE.SphereGeometry(0.38, 12, 10), rockMat);
      shoulder.position.set(side * 0.8, 1.35, 0);
      shoulder.castShadow = true;
      this.registerFadeMesh(shoulder);
      this.model.add(shoulder);
    }

    // Arms
    for (const side of [-1, 1]) {
      const arm = new THREE.Mesh(new THREE.CylinderGeometry(0.22, 0.28, 0.9, 8), rockMat);
      arm.position.set(side * 0.85, 0.55, 0);
      arm.castShadow = true;
      this.registerFadeMesh(arm);
      this.model.add(arm);
    }

    // Head
    const head = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.55, 0.6), darkMat);
    head.position.y = 1.85;
    head.castShadow = true;
    this.registerFadeMesh(head);
    this.model.add(head);

    // Glowing eyes (face toward the player: +Z)
    const eyeMat = new THREE.MeshBasicMaterial({ color: 0xff6622 });
    for (const side of [-1, 1]) {
      const eye = new THREE.Mesh(new THREE.BoxGeometry(0.14, 0.1, 0.05), eyeMat);
      eye.position.set(side * 0.16, 1.9, 0.32);
      this.registerFadeMesh(eye);
      this.model.add(eye);
    }

    // Beine (Gruppen mit Hüft-Pivot für die Laufanimation)
    for (const side of [-1, 1]) {
      const leg = new THREE.Group();
      leg.position.set(side * 0.35, 0.6, 0);
      this.model.add(leg);
      const thigh = new THREE.Mesh(new THREE.CylinderGeometry(0.14, 0.18, 0.35, 6), rockMat);
      thigh.position.y = -0.17;
      this.registerFadeMesh(thigh);
      leg.add(thigh);
      const foot = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.12, 0.4), darkMat);
      foot.position.set(0, -0.5, 0.06);
      this.registerFadeMesh(foot);
      leg.add(foot);
      if (side < 0) {
        this.legL = leg;
      } else {
        this.legR = leg;
      }
    }
  }

  playAnim() {
    // Procedural visuals only
  }

  updateAnimation(dt: number) {
    this.updateFadeDeath(dt, { duration: 1.2, sink: 0.5 });
  }

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

    // Heavy footsteps
    this.body.position.y = 0.15 + Math.abs(Math.sin(this.stepTime * 3)) * 0.07;

    const toPlayer = new THREE.Vector3()
      .subVectors(game.player.body.position, this.body.position);
    toPlayer.y = 0;
    const dist = toPlayer.length();
    let moved = false;
    if (dist > 0.1) {
      const dir = toPlayer.normalize();
      this.body.lookAt(
        this.body.position.x + dir.x,
        this.body.position.y,
        this.body.position.z + dir.z
      );
      let moveDir = dir.multiplyScalar(this.speed);
      if (this.knockback > 0) {
        moveDir = dir.multiplyScalar(-this.speed);
        this.knockback -= dt;
      }
      this.body.position.x += moveDir.x * dt;
      this.body.position.z += moveDir.z * dt;
      game.clampToArena(this.body.position);
      moved = true;
    }

    // Laufanimation: Beine gegengleich im Takt der Schritte, Arme leicht mit
    this.walkAmp += ((moved ? 0.5 : 0) - this.walkAmp) * Math.min(1, dt * 8);
    const swing = Math.sin(this.stepTime * 3) * this.walkAmp;
    this.legL.rotation.x = swing;
    this.legR.rotation.x = -swing;
    if (this.armL) this.armL.rotation.x = -swing * 0.4;
    if (this.armR) this.armR.rotation.x = swing * 0.4;
  }

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