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

const TICK = 0.5;
const TICK_DAMAGE = 4;
const SLOW_REFRESH = 0.15;

export class InkPuddle {
  body: THREE.Group;
  private radius: number;
  private life: number;
  private tickTimer = 0;
  private puffs: THREE.Mesh[] = [];

  constructor(position: THREE.Vector3, radius = 3.5, duration = 6) {
    this.radius = radius;
    this.life = duration;
    this.body = new THREE.Group();
    this.body.position.set(position.x, 0.1, position.z);

    const puffGeom = new THREE.SphereGeometry(1, 12, 10);
    const puffMat = new THREE.MeshToonMaterial({
      color: 0x552277,
      transparent: true,
      opacity: 0.35,
      depthWrite: false,
    });

    for (let i = 0; i < 6; i++) {
      const puff = new THREE.Mesh(puffGeom, puffMat);
      const a = (i / 6) * Math.PI * 2;
      puff.position.set(
        Math.cos(a) * this.radius * 0.4,
        0.3 + Math.random() * 0.3,
        Math.sin(a) * this.radius * 0.4
      );
      puff.scale.setScalar(this.radius * (0.22 + Math.random() * 0.12));
      this.body.add(puff);
      this.puffs.push(puff);
    }
  }

  update(dt: number, game: Game): boolean {
    this.life -= dt;
    if (this.life <= 0) return false;

    const fade = Math.min(1, this.life / 0.6);
    for (const puff of this.puffs) {
      (puff.material as THREE.MeshToonMaterial).opacity = 0.35 * fade;
      puff.rotation.y += dt * 0.3;
    }

    if (game.player.health > 0) {
      const dist = Math.hypot(
        game.player.body.position.x - this.body.position.x,
        game.player.body.position.z - this.body.position.z
      );
      if (dist < this.radius) {
        game.player.slowTimer = SLOW_REFRESH;
        this.tickTimer -= dt;
        if (this.tickTimer <= 0) {
          this.tickTimer = TICK;
          game.player.damage(TICK_DAMAGE, this.body.position);
          game.triggerInkVignette();
        }
      }
    }
    return true;
  }

  dispose() {
    this.body.removeFromParent();
    for (const puff of this.puffs) {
      puff.geometry.dispose();
      (puff.material as THREE.Material).dispose();
    }
  }
}
