import { system, world, Player } from "@minecraft/server";

world.afterEvents.projectileHitEntity.subscribe((eventData) => {
	const hitLocation = eventData.location;
	const projectile = eventData.projectile;
	const dimension = eventData.dimension;

	if (projectile.typeId == "gs_cb:frost_strider_base_projectile") {
		dimension.spawnParticle("gs_cb:normal_ice_spit_explodes_1", hitLocation);
		dimension.spawnParticle("gs_cb:normal_ice_spit_explodes_2", hitLocation);
	}
	if (projectile.typeId == "gs_cb:frost_strider_rapid_projectile") {
		dimension.spawnParticle("gs_cb:normal_ice_spit_explodes_1", hitLocation);
		dimension.spawnParticle("gs_cb:normal_ice_spit_explodes_2", hitLocation);
	}
	if (projectile.typeId == "gs_cb:frost_strider_charged_projectile") {
		dimension.spawnParticle("gs_cb:charged_ice_spit_explodes_1", hitLocation);
		dimension.spawnParticle("gs_cb:charged_ice_spit_explodes_2", hitLocation);
		dimension.spawnParticle("gs_cb:charged_ice_spit_explodes_3", hitLocation);
	}
	if (projectile.typeId == "gs_cb:magma_wither_single_red_fire_projectile" || projectile.typeId == "gs_cb:magma_wither_mortar_red_fire_projectile" || projectile.typeId == "gs_cb:magma_wither_rapid_red_fire_projectile") {
		dimension.spawnParticle("gs_cb:red_fireball_explode_midair_1", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_midair_2", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_midair_3", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_midair_4", hitLocation);
	}
	if (projectile.typeId == "gs_cb:magma_wither_single_blue_fire_projectile" || projectile.typeId == "gs_cb:magma_wither_mortar_blue_fire_projectile" || projectile.typeId == "gs_cb:magma_wither_rapid_blue_fire_projectile") {
		dimension.spawnParticle("gs_cb:blue_fireball_explode_midair_1", hitLocation);
		dimension.spawnParticle("gs_cb:blue_fireball_explode_midair_2", hitLocation);
		dimension.spawnParticle("gs_cb:blue_fireball_explode_midair_3", hitLocation);
		dimension.spawnParticle("gs_cb:blue_fireball_explode_midair_4", hitLocation);
		dimension.spawnParticle("gs_cb:blue_fireball_explode_midair_5", hitLocation);
	}
});

world.afterEvents.projectileHitBlock.subscribe((eventData) => {
	const hitLocation = eventData.location;
	const projectile = eventData.projectile;
	const dimension = eventData.dimension;

	if (projectile.typeId == "gs_cb:frost_strider_base_projectile") {
		dimension.spawnParticle("gs_cb:normal_ice_spit_explodes_1", hitLocation);
		dimension.spawnParticle("gs_cb:normal_ice_spit_explodes_2", hitLocation);
	}
	if (projectile.typeId == "gs_cb:frost_strider_charged_projectile") {
		dimension.spawnParticle("gs_cb:charged_ice_spit_explodes_1", hitLocation);
		dimension.spawnParticle("gs_cb:charged_ice_spit_explodes_2", hitLocation);
		dimension.spawnParticle("gs_cb:charged_ice_spit_explodes_3", hitLocation);
	}
	if (projectile.typeId == "gs_cb:magma_wither_single_red_fire_projectile" || projectile.typeId == "gs_cb:magma_wither_mortar_red_fire_projectile" || projectile.typeId == "gs_cb:magma_wither_rapid_red_fire_projectile") {
		dimension.spawnParticle("gs_cb:red_fireball_explode_ground_1", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_ground_2", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_ground_3", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_ground_4", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_ground_5", hitLocation);
		dimension.spawnParticle("gs_cb:red_fireball_explode_ground_6", hitLocation);
	}

});

system.afterEvents.scriptEventReceive.subscribe((eventData) => {
	const { id, sourceEntity } = eventData;
	if (!sourceEntity) return;
	let variant = sourceEntity.getComponent("variant")?.value;
	let movement = sourceEntity.getComponent("minecraft:movement");

	const ATTACK_DELAYS = {
		"gs_cb:mortar_projectile_l": 65,
		"gs_cb:mortar_projectile_r": 65,
		"gs_cb:mortar_projectile_m": 65,
		"gs_cb:mortar_projectile_a": 65,
		"gs_cb:rapid_projectile_l": 121,
		"gs_cb:rapid_projectile_r": 121,
		"gs_cb:rapid_projectile_m": 121,
		"gs_cb:rapid_projectile_a": 121,
		"gs_cb:single_projectile_l": 21,
		"gs_cb:single_projectile_r": 21,
		"gs_cb:single_projectile_m": 21,
		"gs_cb:single_projectile_a": 21
	};

	function getLeftOffset(viewDir, distance = 1.75) {
		return {
			x: -viewDir.z * distance,
			y: viewDir.y - 0.5,
			z: viewDir.x * distance
		};
	}

	function getRightOffset(viewDir, distance = 1.75) {
		return {
			x: viewDir.z * distance,
			y: viewDir.y - 0.5,
			z: -viewDir.x * distance
		};
	}

	function getDirection(vector1, vector2) {
		const distance = Math.sqrt(
			(vector1.x - vector2.x) ** 2 +
			(vector1.y - vector2.y) ** 2 +
			(vector1.z - vector2.z) ** 2
		) || 0.001;
		return {
			x: ((vector2.x - vector1.x) / distance) * 4,
			y: ((vector2.y - vector1.y) / distance) * 4,
			z: ((vector2.z - vector1.z) / distance) * 4
		};
	}
	function isEntityValid(entity) {
		try {
			return !!entity?.isValid();
		} catch {
			return false;
		}
	}

	function spawnAndShootProjectile(entity, position, viewDir, projectileID) {
		if (!isEntityValid(entity)) return;
		let fireBall
		let projectile;
		try {
			fireBall = entity.dimension.spawnEntity(projectileID, position);
			projectile = fireBall?.getComponent("minecraft:projectile");
		} catch (e) {
			console.warn(e)
		}
		if (projectile) {
			projectile.owner = entity;
			let player = entity.dimension.getPlayers({ location: position, closest: 1 })[0];
			projectile.shoot(getDirection(position, player.location), { uncertainty: 0 });
		}
	}

	if (sourceEntity.isBaby) return;

	const attackDelay = ATTACK_DELAYS[id] || 40;

	system.runTimeout(() => {
		if (!isEntityValid(sourceEntity)) return;
		if (sourceEntity.isBaby) return;
		const shoot = (animation, projectileID, positions, count = 1, interval = 0) => {
			sourceEntity.triggerEvent("gs_cb:start_attacking");
			sourceEntity.triggerEvent(`gs_cb:add_animation_${animation}`);

			let isShooting = true;

			// Start movement loop
			const movementLoopId = system.runInterval(() => {
				if (isEntityValid(sourceEntity) && !isShooting) {
					system.clearRun(movementLoopId);
					movement.setCurrentValue(0.05); // <-- Final reset after loop ends
					return;
				} else if (isEntityValid(sourceEntity) && isShooting) {
					movement.setCurrentValue(0.0); // <-- Active movement
				}
				else {
					return;
				}
			}, 1);

			system.runTimeout(() => {
				if (!isEntityValid(sourceEntity)) return;
				if (sourceEntity.isBaby) return;
				sourceEntity.triggerEvent("gs_cb:add_attack_cooldown");

				const fireProjectiles = (remaining) => {
					if (!isEntityValid(sourceEntity)) return;

					// 🧠 Get the current view and position each time a shot is fired
					const viewDir = sourceEntity.getViewDirection();
					const headLocation = sourceEntity.getHeadLocation();

					const leftPos = {
						x: headLocation.x + getLeftOffset(viewDir, 1.75).x,
						y: headLocation.y - 0.5,
						z: headLocation.z + getLeftOffset(viewDir, 1.75).z
					};
					const rightPos = {
						x: headLocation.x + getRightOffset(viewDir, 1.75).x,
						y: headLocation.y - 0.5,
						z: headLocation.z + getRightOffset(viewDir, 1.75).z
					};

					const projectilePositions = positions.map(pos => {
						switch (pos) {
							case "left": return leftPos;
							case "right": return rightPos;
							case "mid": return headLocation;
							default: return pos; // fallback if you passed a raw position
						}
					});

					projectilePositions.forEach(pos => {
						spawnAndShootProjectile(sourceEntity, pos, viewDir, projectileID);
					});

					if (remaining > 1) {
						system.runTimeout(() => fireProjectiles(remaining - 1), interval);
					}
				};

				fireProjectiles(count);

				// Calculate total duration of the shooting sequence
				const shootDuration = interval * (count - 1) + 30;

				system.runTimeout(() => {
					if (!isEntityValid(sourceEntity)) return;

					isShooting = false; // This will trigger the movement reset on next tick

					sourceEntity.triggerEvent("gs_cb:remove_attack_cooldown");
					sourceEntity.triggerEvent("gs_cb:stop_attacking");
				}, shootDuration);
			}, 1);
		};



		if (variant == 1) {
			switch (id) {

				// Simple projectile
				case "gs_cb:single_projectile_l":
					shoot("leftFireBall", "gs_cb:magma_wither_single_blue_fire_projectile", ["left"]);
					break;
				case "gs_cb:single_projectile_r":
					shoot("rightFireBall", "gs_cb:magma_wither_single_blue_fire_projectile", ["right"]);
					break;
				case "gs_cb:single_projectile_m":
					shoot("midFireBall", "gs_cb:magma_wither_single_blue_fire_projectile", ["mid"]);
					break;
				case "gs_cb:single_projectile_a":
					shoot("allFireBall", "gs_cb:magma_wither_single_blue_fire_projectile", ["left", "right", "mid"]);
					break;

				// Rapid projectile
				case "gs_cb:rapid_projectile_l":
					shoot("leftFireBallRapid", "gs_cb:magma_wither_rapid_blue_fire_projectile", ["left"], 6, 10);
					break;

				case "gs_cb:rapid_projectile_r":
					shoot("rightFireBallRapid", "gs_cb:magma_wither_rapid_blue_fire_projectile", ["right"], 6, 10);
					break;

				case "gs_cb:rapid_projectile_m":
					shoot("midFireBallRapid", "gs_cb:magma_wither_rapid_blue_fire_projectile", ["mid"], 6, 10);
					break;

				case "gs_cb:rapid_projectile_a":
					shoot("allFireBallRapid", "gs_cb:magma_wither_rapid_blue_fire_projectile", ["left", "right", "mid"], 6, 10);
					break;

				// Mortar projectiles
				case "gs_cb:mortar_projectile_l":
					shoot("leftFireMortar", "gs_cb:magma_wither_mortar_blue_fire_projectile", ["left"]);
					break;
				case "gs_cb:mortar_projectile_r":
					shoot("rightFireMortar", "gs_cb:magma_wither_mortar_blue_fire_projectile", ["right"]);
					break;
				case "gs_cb:mortar_projectile_m":
					shoot("midFireMortar", "gs_cb:magma_wither_mortar_blue_fire_projectile", ["mid"]);
					break;
				case "gs_cb:mortar_projectile_a":
					shoot("allFireMortar", "gs_cb:magma_wither_mortar_blue_fire_projectile", ["left", "right", "mid"]);
					break;
			}
		}
		else {
			switch (id) {

				// Simple projectile
				case "gs_cb:single_projectile_l":
					shoot("leftFireBall", "gs_cb:magma_wither_single_red_fire_projectile", ["left"]);
					break;
				case "gs_cb:single_projectile_r":
					shoot("rightFireBall", "gs_cb:magma_wither_single_red_fire_projectile", ["right"]);
					break;
				case "gs_cb:single_projectile_m":
					shoot("midFireBall", "gs_cb:magma_wither_single_red_fire_projectile", ["mid"]);
					break;
				case "gs_cb:single_projectile_a":
					shoot("allFireBall", "gs_cb:magma_wither_single_red_fire_projectile", ["left", "right", "mid"]);
					break;

				// Rapid projectile
				case "gs_cb:rapid_projectile_l":
					shoot("leftFireBallRapid", "gs_cb:magma_wither_rapid_red_fire_projectile", ["left"], 6, 10);
					break;

				case "gs_cb:rapid_projectile_r":
					shoot("rightFireBallRapid", "gs_cb:magma_wither_rapid_red_fire_projectile", ["right"], 6, 10);
					break;

				case "gs_cb:rapid_projectile_m":
					shoot("midFireBallRapid", "gs_cb:magma_wither_rapid_red_fire_projectile", ["mid"], 6, 10);
					break;

				case "gs_cb:rapid_projectile_a":
					shoot("allFireBallRapid", "gs_cb:magma_wither_rapid_red_fire_projectile", ["left", "right", "mid"], 6, 10);
					break;

				// Mortar projectiles
				case "gs_cb:mortar_projectile_l":
					shoot("leftFireMortar", "gs_cb:magma_wither_mortar_red_fire_projectile", ["left"]);
					break;
				case "gs_cb:mortar_projectile_r":
					shoot("rightFireMortar", "gs_cb:magma_wither_mortar_red_fire_projectile", ["right"]);
					break;
				case "gs_cb:mortar_projectile_m":
					shoot("midFireMortar", "gs_cb:magma_wither_mortar_red_fire_projectile", ["mid"]);
					break;
				case "gs_cb:mortar_projectile_a":
					shoot("allFireMortar", "gs_cb:magma_wither_mortar_red_fire_projectile", ["left", "right", "mid"]);
					break;
			}
		}
	}, attackDelay);
});


