/*
RSK World – Tower Defense 3D (Enemy GLTF)
For support, licensing, or custom development inquiries: help@rskworld.in • Phone/WhatsApp: +91 9330539277
Website: RSK World • Business Inquiries: help@rskworld.in
🤝 Contributing: Suggestions and improvements are welcome!
*/

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

export class EnemyGLTF {
	constructor(pathPoints, url, config = {}) {
		this.path = pathPoints;
		this.url = url;
		this.currentSegment = 0;
		this.speed = config.speed ?? 3.2;
		this.maxHealth = config.health ?? 60;
		this.health = this.maxHealth;
		this.reachedEnd = false;
		this.alive = true;
		this.radius = config.radius ?? 0.6;
		this.mixer = null;
		this.group = new THREE.Group();
		this.group.position.copy(this.path[0]);
		this._lastMoveDir = new THREE.Vector3(0, 0, 1);
		this._scale = config.scale ?? 1.0;
		this._animName = config.animName ?? null;
		this._loaded = false;

		this._loadModel();
	}

	_loadModel() {
		const loader = new GLTFLoader();
		loader.load(this.url, (gltf) => {
			const root = gltf.scene;
			root.traverse((o) => { if (o.isMesh) { o.castShadow = true; o.receiveShadow = true; } });
			root.scale.setScalar(this._scale);
			this.group.add(root);
			if (gltf.animations && gltf.animations.length) {
				this.mixer = new THREE.AnimationMixer(root);
				let clip = null;
				if (this._animName) {
					clip = gltf.animations.find(a => a.name === this._animName || a.name.toLowerCase().includes(this._animName.toLowerCase()));
				}
				clip = clip || gltf.animations.find(a => /walk|run/i.test(a.name)) || gltf.animations[0];
				this.mixer.clipAction(clip).play();
			}
			this._loaded = true;
		}, undefined, (err) => {
			const geo = new THREE.ConeGeometry(0.6, 1.8, 12);
			const mat = new THREE.MeshStandardMaterial({ color: 0x22d3ee });
			const m = new THREE.Mesh(geo, mat);
			m.castShadow = true; m.receiveShadow = true;
			this.group.add(m);
			this._loaded = true;
		});
	}

	addTo(scene) { scene.add(this.group); }
	removeFrom(scene) { scene.remove(this.group); }

	takeDamage(amount) {
		if (!this.alive) return;
		this.health -= amount;
		if (this.health <= 0) this.alive = false;
	}

	_faceDirection(dir) {
		const yaw = Math.atan2(dir.x, dir.z);
		this.group.rotation.y = yaw;
	}

	_stepAlongPath(move) {
		while (move > 0 && this.currentSegment < this.path.length - 1) {
			const a = this.path[this.currentSegment];
			const b = this.path[this.currentSegment + 1];
			const pos = this.group.position;
			const toB = new THREE.Vector3().subVectors(b, pos);
			const distToB = toB.length();
			if (move >= distToB) {
				pos.copy(b);
				this.currentSegment++;
				move -= distToB;
			} else {
				toB.normalize();
				pos.addScaledVector(toB, move);
				this._lastMoveDir = toB;
				move = 0;
			}
		}
		if (this.currentSegment >= this.path.length - 1) this.reachedEnd = true;
	}

	update(delta) {
		if (!this.alive) return;
		if (this.mixer) this.mixer.update(delta);
		const move = this.speed * delta;
		this._stepAlongPath(move);
		this._faceDirection(this._lastMoveDir);
	}
}
