/*
RSK World – Tower Defense 3D (EnemyToon)
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 EnemyToon {
	constructor(pathPoints, config = {}) {
		this.path = pathPoints;
		this.currentSegment = 0;
		this.speed = config.speed ?? 3.2;
		this.maxHealth = config.health ?? 70;
		this.health = this.maxHealth;
		this.reachedEnd = false;
		this.alive = true;
		this.scale = config.scale ?? 1.0;
		this.radius = config.radius ?? (0.6 * this.scale);
		this.variant = (config.variant ?? 'barbarian').toLowerCase();
		this._animTime = 0;
		this._lastMoveDir = new THREE.Vector3(0, 0, 1);

		this.group = this._createCharacter();
		this.group.position.copy(this.path[0]);
	}

	_colorsForVariant() {
		switch (this.variant) {
			case 'archer':
				return { skin: 0xffe0c0, cloth: 0x2e7d32, hair: 0x2dd4bf, accent: 0x1f2937 };
			case 'giant':
				return { skin: 0xffd0a8, cloth: 0x9c6644, hair: 0xcc5500, accent: 0x7f1d1d };
			case 'barbarian':
			default:
				return { skin: 0xffdbc0, cloth: 0x8b5a2b, hair: 0xffd54f, accent: 0x8b0000 };
		}
	}

	_createCharacter() {
		const g = new THREE.Group();
		const c = this._colorsForVariant();
		const s = this.scale;

		const legLen = 0.9 * s;
		const torsoH = 1.2 * s;
		const torsoW = 0.8 * s;
		const headR = 0.45 * s;

		// Legs
		const legGeo = new THREE.BoxGeometry(0.25 * s, legLen, 0.25 * s);
		const bootGeo = new THREE.BoxGeometry(0.28 * s, 0.18 * s, 0.35 * s);
		const legMat = new THREE.MeshStandardMaterial({ color: c.skin, roughness: 0.8 });
		const bootMat = new THREE.MeshStandardMaterial({ color: 0x3f3f46, roughness: 0.6 });
		const legL = new THREE.Mesh(legGeo, legMat); legL.castShadow = true;
		const legR = new THREE.Mesh(legGeo, legMat); legR.castShadow = true;
		legL.position.set(-0.22 * s, legLen / 2, 0);
		legR.position.set(0.22 * s, legLen / 2, 0);
		const bootL = new THREE.Mesh(bootGeo, bootMat); bootL.position.set(-0.22 * s, 0.09 * s, 0.08 * s);
		const bootR = new THREE.Mesh(bootGeo, bootMat); bootR.position.set(0.22 * s, 0.09 * s, 0.08 * s);
		g.add(legL); g.add(legR); g.add(bootL); g.add(bootR);
		this._legL = legL; this._legR = legR;

		// Torso
		const torsoGeo = new THREE.BoxGeometry(torsoW, torsoH, torsoW * 0.7);
		const torsoMat = new THREE.MeshStandardMaterial({ color: c.cloth, roughness: 0.9 });
		const torso = new THREE.Mesh(torsoGeo, torsoMat); torso.castShadow = true; torso.receiveShadow = true;
		torso.position.y = legLen + torsoH / 2;
		g.add(torso);

		// Belt
		const beltGeo = new THREE.BoxGeometry(torsoW * 1.02, 0.14 * s, torsoW * 0.75);
		const beltMat = new THREE.MeshStandardMaterial({ color: c.accent, roughness: 0.7 });
		const belt = new THREE.Mesh(beltGeo, beltMat); belt.position.y = legLen + 0.35 * s;
		g.add(belt);

		// Arms
		const armGeo = new THREE.BoxGeometry(0.22 * s, 0.9 * s, 0.22 * s);
		const armMat = new THREE.MeshStandardMaterial({ color: c.skin, roughness: 0.8 });
		const armL = new THREE.Mesh(armGeo, armMat); armL.castShadow = true;
		const armR = new THREE.Mesh(armGeo, armMat); armR.castShadow = true;
		armL.position.set(-torsoW / 2 - 0.15 * s, legLen + torsoH * 0.55, 0);
		armR.position.set(torsoW / 2 + 0.15 * s, legLen + torsoH * 0.55, 0);
		g.add(armL); g.add(armR);
		this._armL = armL; this._armR = armR;

		// Head
		const headGeo = new THREE.SphereGeometry(headR, 24, 18);
		const headMat = new THREE.MeshStandardMaterial({ color: c.skin, roughness: 0.6 });
		const head = new THREE.Mesh(headGeo, headMat); head.castShadow = true;
		head.position.y = legLen + torsoH + headR + 0.05 * s;
		g.add(head);

		// Hair / hood cap
		const hairGeo = new THREE.SphereGeometry(headR * 1.02, 18, 14, 0, Math.PI * 2, 0, Math.PI / 2);
		const hairMat = new THREE.MeshStandardMaterial({ color: c.hair, roughness: 0.7 });
		const hair = new THREE.Mesh(hairGeo, hairMat);
		hair.rotation.x = Math.PI;
		hair.position.y = head.position.y + 0.02 * s;
		g.add(hair);

		// Simple eyes
		const eyeGeo = new THREE.SphereGeometry(0.05 * s, 8, 8);
		const eyeMat = new THREE.MeshStandardMaterial({ color: 0x0f172a });
		const eyeL = new THREE.Mesh(eyeGeo, eyeMat);
		const eyeR = new THREE.Mesh(eyeGeo, eyeMat);
		eyeL.position.set(-0.12 * s, head.position.y + 0.05 * s, headR - 0.02 * s);
		eyeR.position.set(0.12 * s, head.position.y + 0.05 * s, headR - 0.02 * s);
		g.add(eyeL); g.add(eyeR);

		// Variant props (very simple weapon cues)
		if (this.variant === 'barbarian') {
			const swordGeo = new THREE.BoxGeometry(0.08 * s, 0.9 * s, 0.12 * s);
			const swordMat = new THREE.MeshStandardMaterial({ color: 0xbdbdbd, metalness: 0.6, roughness: 0.3 });
			const sword = new THREE.Mesh(swordGeo, swordMat); sword.castShadow = true;
			sword.position.set(torsoW / 2 + 0.15 * s, legLen + 0.3 * s, 0.15 * s);
			g.add(sword);
		}
		if (this.variant === 'archer') {
			const quiverGeo = new THREE.CylinderGeometry(0.09 * s, 0.09 * s, 0.6 * s, 10);
			const quiverMat = new THREE.MeshStandardMaterial({ color: 0x3f3f46 });
			const quiver = new THREE.Mesh(quiverGeo, quiverMat); quiver.rotation.z = 0.3; quiver.position.set(-0.25 * s, legLen + 0.9 * s, -0.25 * s);
			g.add(quiver);
		}

		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;
	}

	_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;
		const move = this.speed * delta;
		this._stepAlongPath(move);
		this._faceDirection(this._lastMoveDir);

		// Walk animation
		this._animTime += delta * 6.5;
		const s = Math.sin(this._animTime);
		if (this._legL && this._legR) {
			this._legL.rotation.x = s * 0.6;
			this._legR.rotation.x = -s * 0.6;
		}
		if (this._armL && this._armR) {
			this._armL.rotation.x = -s * 0.4;
			this._armR.rotation.x = s * 0.4;
		}
		this.group.position.y = Math.max(0, Math.abs(s) * 0.05 * this.scale);
	}
}
