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

export class Golem extends Brute {
  constructor() {
    super();
    this.health = 800;
    this.maxHealth = 800;
    this.isBoss = true;
    this.displayName = 'Golem';
    this.speed = 3;
    this.xp = 80;
    this.contactDps = 50;
    this.contactRadius = 3.4;
    this.guaranteedDrop = true;

    // Brute-Standardmodell verwerfen und als Fels-Golem neu aufbauen
    this.model.clear();

    const rockMat = new THREE.MeshToonMaterial({ color: 0x6a6a78 });
    const darkMat = new THREE.MeshToonMaterial({ color: 0x3c3c46 });
    const mossMat = new THREE.MeshToonMaterial({ color: 0x4a8a4a });
    const eyeMat = new THREE.MeshBasicMaterial({ color: 0xff6622 });
    // Facettierte Fels-Optik: flache Normalen auf der unindizierten Geometrie
    const rockGeom = (r: number) => {
      const g = new THREE.DodecahedronGeometry(r);
      g.computeVertexNormals();
      return g;
    };

    // Becken + Rumpf (facettierte Felsbrocken)
    const pelvis = new THREE.Mesh(rockGeom(0.42), darkMat);
    pelvis.scale.set(1.2, 0.8, 0.9);
    pelvis.position.y = 0.75;
    this.registerFadeMesh(pelvis);
    this.model.add(pelvis);
    const torso = new THREE.Mesh(rockGeom(0.72), rockMat);
    torso.scale.set(1.25, 1.05, 0.95);
    torso.position.y = 1.4;
    torso.castShadow = true;
    this.registerFadeMesh(torso);
    this.model.add(torso);

    // Glühender Kern in der Brust (+Z)
    const core = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.36, 0.08), eyeMat);
    core.position.set(0, 1.45, 0.66);
    this.model.add(core);

    // Kopf mit Stirnplatte, Augen und Kiefer (+Z)
    const head = new THREE.Mesh(rockGeom(0.38), rockMat);
    head.position.y = 2.15;
    head.castShadow = true;
    this.registerFadeMesh(head);
    this.model.add(head);
    const brow = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.1, 0.12), darkMat);
    brow.position.set(0, 2.3, 0.3);
    this.registerFadeMesh(brow);
    this.model.add(brow);
    for (const side of [-1, 1]) {
      const eye = new THREE.Mesh(new THREE.BoxGeometry(0.13, 0.09, 0.05), eyeMat);
      eye.position.set(side * 0.15, 2.15, 0.33);
      this.model.add(eye);
    }
    const jaw = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.12, 0.2), darkMat);
    jaw.position.set(0, 1.93, 0.25);
    this.registerFadeMesh(jaw);
    this.model.add(jaw);

    // Felsstacheln auf dem Rücken
    for (const side of [-1, 1]) {
      const spike = new THREE.Mesh(new THREE.ConeGeometry(0.14, 0.45, 5), darkMat);
      spike.position.set(side * 0.3, 1.75, -0.6);
      spike.rotation.x = 0.6;
      this.registerFadeMesh(spike);
      this.model.add(spike);
    }

    // Moosflecken
    const mossSpots: [number, number, number, number][] = [
      [-0.9, 2.15, 0.1, 0.12],
      [0.5, 1.95, 0.3, 0.1],
      [0.3, 2.4, -0.1, 0.09],
    ];
    for (const [x, y, z, r] of mossSpots) {
      const moss = new THREE.Mesh(rockGeom(r), mossMat);
      moss.position.set(x, y, z);
      this.registerFadeMesh(moss);
      this.model.add(moss);
    }

    // Schultern + gegliederte Arme (Schulter-Pivot für Laufanimation)
    for (const side of [-1, 1]) {
      const shoulder = new THREE.Mesh(rockGeom(0.48), rockMat);
      shoulder.position.set(side * 0.95, 1.75, 0);
      shoulder.castShadow = true;
      this.registerFadeMesh(shoulder);
      this.model.add(shoulder);

      const arm = new THREE.Group();
      arm.position.set(side * 0.95, 1.7, 0);
      this.model.add(arm);
      const upperArm = new THREE.Mesh(new THREE.CylinderGeometry(0.16, 0.2, 0.55, 6), rockMat);
      upperArm.position.y = -0.3;
      this.registerFadeMesh(upperArm);
      arm.add(upperArm);
      const elbow = new THREE.Mesh(rockGeom(0.18), darkMat);
      elbow.position.y = -0.6;
      this.registerFadeMesh(elbow);
      arm.add(elbow);
      const foreArm = new THREE.Mesh(new THREE.CylinderGeometry(0.14, 0.18, 0.5, 6), darkMat);
      foreArm.position.y = -0.85;
      this.registerFadeMesh(foreArm);
      arm.add(foreArm);
      const fist = new THREE.Mesh(rockGeom(0.24), rockMat);
      fist.scale.set(1, 0.8, 1.1);
      fist.position.y = -1.15;
      this.registerFadeMesh(fist);
      arm.add(fist);
      if (side < 0) {
        this.armL = arm;
      } else {
        this.armR = arm;
      }
    }

    // Beine (Hüft-Pivot für Laufanimation)
    for (const side of [-1, 1]) {
      const leg = new THREE.Group();
      leg.position.set(side * 0.4, 0.75, 0);
      this.model.add(leg);
      const thigh = new THREE.Mesh(new THREE.CylinderGeometry(0.18, 0.24, 0.4, 6), rockMat);
      thigh.position.y = -0.18;
      this.registerFadeMesh(thigh);
      leg.add(thigh);
      const knee = new THREE.Mesh(rockGeom(0.16), darkMat);
      knee.position.y = -0.38;
      this.registerFadeMesh(knee);
      leg.add(knee);
      const shin = new THREE.Mesh(new THREE.CylinderGeometry(0.14, 0.18, 0.35, 6), darkMat);
      shin.position.y = -0.52;
      this.registerFadeMesh(shin);
      leg.add(shin);
      const foot = new THREE.Mesh(new THREE.BoxGeometry(0.32, 0.16, 0.5), rockMat);
      foot.position.set(0, -0.67, 0.08);
      this.registerFadeMesh(foot);
      leg.add(foot);
      if (side < 0) {
        this.legL = leg;
      } else {
        this.legR = leg;
      }
    }

    this.model.scale.setScalar(2.1);

    // Krone (Boss-Markierung)
    const crownMat = new THREE.MeshToonMaterial({ color: 0xffcc33 });
    const crown = new THREE.Mesh(
      new THREE.ConeGeometry(0.3, 0.4, 8, 1, true),
      crownMat
    );
    crown.position.y = 2.55;
    crown.castShadow = true;
    this.registerFadeMesh(crown);
    this.model.add(crown);
  }

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