import * as THREE from 'three';
import { Weapon } from './Weapon';
import { Player } from './Player';
import { Fireball } from './Fireball';
import { playSound } from './SoundManager';
import { loadGLB } from './MeshLoader';
import { fireballDamage, fireballCooldown, fireballRadius, teleportCooldown } from './Skills';

export class Staff extends Weapon {
  constructor() {
    super();
    this.COOLDOWN1_TIME = 5;
    this.COOLDOWN2_TIME = 50;

    // Fallback geometry
    const shaftGeom = new THREE.CylinderGeometry(0.04, 0.05, 1.0, 8);
    const crystalGeom = new THREE.OctahedronGeometry(0.08);
    const woodMat = new THREE.MeshToonMaterial({ color: 0x8B4513 });
    const crystalMat = new THREE.MeshToonMaterial({ color: 0x4488ff });
    const shaft = new THREE.Mesh(shaftGeom, woodMat);
    shaft.position.y = 0.3;
    shaft.castShadow = true;
    const crystal = new THREE.Mesh(crystalGeom, crystalMat);
    crystal.position.y = 0.9;
    this.mesh.add(shaft);
    this.mesh.add(crystal);

    this.mesh.position.set(0.35, 0.3, 0.35);
    this.mesh.scale.set(0.35, 0.35, 0.35);
    this.mesh.rotation.set(-0.2, 0, -0.2);
  }

  async init() {
    try {
      const gltf = await loadGLB('staff');
      const model = gltf.scene;
      const staffTexture = new THREE.TextureLoader().load('./textures/staff1.png');
      staffTexture.flipY = false;
      staffTexture.colorSpace = THREE.SRGBColorSpace;
      model.traverse((child) => {
        if (child instanceof THREE.Mesh) {
          child.castShadow = true;
          child.material = new THREE.MeshToonMaterial({ map: staffTexture });
        }
      });
      while (this.mesh.children.length > 0) {
        this.mesh.remove(this.mesh.children[0]);
      }
      this.mesh.add(model);
    } catch {
      // Keep fallback
    }
  }

  skill1(groundPoint: THREE.Vector3, player: Player): void {
    const level = player.game.skillSystem.getLevel('fireball');
    if (level <= 0) return;
    if (this.cooldown1 > 0) return;

    this.COOLDOWN1_TIME = fireballCooldown(level);
    this.cooldown1 = this.COOLDOWN1_TIME;

    // Spawn at staff height, fly toward the cursor point
    const spawnPos = player.body.position.clone();
    spawnPos.y += 0.8;

    const dir = new THREE.Vector3()
      .subVectors(groundPoint, spawnPos)
      .normalize()
      .multiplyScalar(25);
    dir.setY(0);

    const fb = new Fireball(spawnPos, dir);
    fb.damage = fireballDamage(level);
    fb.explosionRadius = fireballRadius(level);
    player.game.scene.add(fb.body);
    player.game.fireballs.push(fb);
    playSound('fireball', 0.5);
  }

  skill2(groundPoint: THREE.Vector3, player: Player): void {
    const level = player.game.skillSystem.getLevel('teleport');
    if (level <= 0) return;
    if (this.cooldown2 > 0) return;

    this.COOLDOWN2_TIME = teleportCooldown(level);
    this.cooldown2 = this.COOLDOWN2_TIME;

    const newPos = groundPoint.clone();
    newPos.y = 0.5;
    newPos.x = Math.max(-47, Math.min(47, newPos.x));
    newPos.z = Math.max(-47, Math.min(47, newPos.z));
    player.body.position.copy(newPos);
    playSound('teleport', 0.5);
  }
}
