/*
RSK World – Tower Defense 3D (Enemy Evolution)
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';

export class Enemy {
	constructor(pathPoints, config = {}) {
		this.path = pathPoints;
		this.currentSegment = 0;
		this.speed = config.speed ?? 3.2; 
		this.maxHealth = config.health ?? 50;
		this.health = this.maxHealth;
		this.reachedEnd = false;
		this.alive = true;
		this.radius = config.radius ?? 0.6;
		this.isFlying = config.isFlying ?? false;
		this.variant = config.variant ?? 'default';
		
		this._animTime = 0;
		this.obstacles = config.obstacles ?? [];
		this.attack = { damage: 8, range: 1.1, cooldown: 0.9 };
		this._cd = 0;

		this.group = this._createCharacter();
		this.group.position.copy(this.path[0]);
		if (this.isFlying) {
			this.group.position.y = 4.0; // Fly above ground
		}
	}

	_createCharacter() {
		const g = new THREE.Group();

		if (this.variant === 'dragon') {
			return this._createDragon(g);
		} else if (this.variant === 'crobot') {
			return this._createCrobot(g);
		} else {
			return this._createDefault(g);
		}
	}

	_createDefault(g) {
		const bodyGeo = new THREE.CapsuleGeometry(0.5, 0.8, 4, 8);
		const bodyMat = new THREE.MeshStandardMaterial({ color: 0xef4444, roughness: 0.5 });
		const body = new THREE.Mesh(bodyGeo, bodyMat);
		body.castShadow = true;
		g.add(body);

		const head = new THREE.Mesh(new THREE.SphereGeometry(0.4, 12, 12), new THREE.MeshStandardMaterial({ color: 0x991b1b }));
		head.position.y = 0.9;
		g.add(head);

		this._legL = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.6, 0.2), bodyMat);
		this._legL.position.set(-0.25, -0.6, 0);
		this._legR = this._legL.clone();
		this._legR.position.set(0.25, -0.6, 0);
		g.add(this._legL, this._legR);
		return g;
	}

	_createDragon(g) {
		const body = new THREE.Mesh(new THREE.CapsuleGeometry(0.4, 1.2, 4, 8), new THREE.MeshStandardMaterial({ color: 0x7c3aed }));
		body.rotation.x = Math.PI / 2;
		body.castShadow = true;
		g.add(body);

		const wingGeo = new THREE.PlaneGeometry(1.5, 0.8);
		const wingMat = new THREE.MeshStandardMaterial({ color: 0x4c1d95, side: THREE.DoubleSide });
		this._wingL = new THREE.Mesh(wingGeo, wingMat);
		this._wingL.position.set(-0.8, 0, 0);
		this._wingL.rotation.y = -Math.PI / 4;
		
		this._wingR = this._wingL.clone();
		this._wingR.position.set(0.8, 0, 0);
		this._wingR.rotation.y = Math.PI / 4;
		
		g.add(this._wingL, this._wingR);

		const head = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.4, 0.6), wingMat);
		head.position.z = 0.8;
		g.add(head);

		return g;
	}

	_createCrobot(g) {
		const body = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1.2, 1.2), new THREE.MeshStandardMaterial({ color: 0x334155, metalness: 0.8, roughness: 0.2 }));
		body.castShadow = true;
		g.add(body);

		const eye = new THREE.Mesh(new THREE.PlaneGeometry(0.8, 0.2), new THREE.MeshBasicMaterial({ color: 0xef4444 }));
		eye.position.set(0, 0.2, 0.61);
		g.add(eye);

		this._legL = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.2, 0.8), body.material);
		this._legL.position.set(-0.4, -0.8, 0);
		this._legR = this._legL.clone();
		this._legR.position.set(0.4, -0.8, 0);
		g.add(this._legL, this._legR);
		return g;
	}

	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;
		}
		// Flash effect
		const mat = this.group.children[0].material;
		const oldColor = mat.color.getHex();
		mat.color.set(0xffffff);
		setTimeout(() => mat && mat.color.set(oldColor), 50);
	}

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

	_tryAttackObstacle() {
		if (this.isFlying || this._cd > 0) return false;
		let nearest = null; let bestDist = Infinity;
		for (const o of this.obstacles) {
			const d = o.group.position.distanceTo(this.group.position);
			if (d < bestDist) { bestDist = d; nearest = o; }
		}
		if (nearest && bestDist < this.attack.range + (nearest.radius ?? 0.5)) {
			nearest.hp = Math.max(0, (nearest.hp ?? 100) - this.attack.damage);
			this._cd = this.attack.cooldown;
			if (nearest.hp <= 0) { 
				nearest.removeFrom && nearest.removeFrom(this.group.parent); 
				const idx = this.obstacles.indexOf(nearest); 
				if (idx >= 0) this.obstacles.splice(idx, 1); 
			}
			return true;
		}
		return false;
	}

	_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 segVec = new THREE.Vector3().subVectors(b, a);
			const segLen = segVec.length();
			if (segLen < 1e-5) { this.currentSegment++; continue; }
			const pos = this.group.position;
			const toB = new THREE.Vector3(b.x, this.isFlying ? 4.0 : 0, b.z).sub(pos);
			const distToB = toB.length();
			if (move >= distToB) { pos.copy(new THREE.Vector3(b.x, this.isFlying ? 4.0 : 0, b.z)); 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;
		this._cd = Math.max(0, this._cd - delta);
		const move = this.speed * delta;
		
		if (!this._tryAttackObstacle()) {
			this._stepAlongPath(move);
		}

		const dir = this._lastMoveDir ?? new THREE.Vector3(0, 0, 1);
		this._faceDirection(dir);
		
		this._animTime += delta * 6.5;
		if (this.variant === 'dragon' && this._wingL) {
			const flap = Math.sin(this._animTime * 2) * 0.8;
			this._wingL.rotation.z = flap;
			this._wingR.rotation.z = -flap;
		} else if (this._legL) {
			const walk = Math.sin(this._animTime);
			this._legL.rotation.x = walk * 0.7;
			this._legR.rotation.x = -walk * 0.7;
			if (!this.isFlying) {
				this.group.position.y = Math.max(0, Math.abs(walk) * 0.06);
			}
		}
	}
}
