import { system, InputPermissionCategory, EquipmentSlot } from "@minecraft/server";
import * as utils from "../utils";
import * as camera from "../camera";
import { damageItem } from "../inventory_utils";

const CONFIG = {
		COOLDOWN: 1 * 20,
		DASH_AMOUNT: 5.5,
		VERTICAL_DASH_AMOUNT: 0.2,
		DASH_DELAY: 8,
		TP_TRANSITION_DURATION: 0.5,
		EFFECT_DELAY: 10,
		CAMERA_DURATION: 30,
		RANGE: 5,
		DAMAGE_AMOUNT: 12,
};

export async function onItemUse(event) {
		const player = event.source;
		if (player.getItemCooldown("tcs_cwp:ender_dagger") > 0) return;
		player.startItemCooldown("tcs_cwp:ender_dagger", CONFIG.COOLDOWN);
		damageItem(player, EquipmentSlot.Mainhand, 1);

		utils.playSound(player, `@a[x=${player.location.x}, y=${player.location.y}, z=${player.location.z}, r=2]`, 'tcs_cwp:ender_dagger_dash');

		if (player.getGameMode() === "survival") damageItem(player, EquipmentSlot.Mainhand, 1);

		utils.playAnimation(player, "animation.tcs_cwp.player.dash");
		camera.switchToThirdPerson(player, CONFIG.TP_TRANSITION_DURATION);

		system.waitTicks(CONFIG.DASH_DELAY).then(() => performDash(player));
		system.waitTicks(CONFIG.EFFECT_DELAY).then(() => dealDamage(player));
		system.waitTicks(CONFIG.CAMERA_DURATION).then(() => camera.reset(player));
}


function performDash(player) {
		const dir = player.getViewDirection();

		player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, false);
		system.runTimeout(() => {
			player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, true);
		}, 24);

		utils.applyKnockback(
			player,
			dir.x,
			dir.z,
			CONFIG.DASH_AMOUNT,
			CONFIG.VERTICAL_DASH_AMOUNT
		);

		let distance = 0;
		let loc = { ...player.location };
		const step = 1;
		const maxDist = CONFIG.DASH_AMOUNT * (1 + CONFIG.VERTICAL_DASH_AMOUNT);

		const dist = 9;
		const particleLoc = {
			x: player.location.x + dir.x * dist,
			y: player.location.y + 1,
			z: player.location.z + dir.z * dist,
		};
		// player.dimension.spawnParticle("tcs_cwp:teleport", particleLoc, undefined);
		utils.runCommand(`particle tcs_cwp:teleport ${particleLoc.x} ${particleLoc.y} ${particleLoc.z}`);
		system.runTimeout(() => {
			utils.runCommand(`particle tcs_cwp:teleport_hit ${particleLoc.x} ${particleLoc.y} ${particleLoc.z}`);
			utils.playSound(player, `@a[x=${player.location.x}, y=${player.location.y}, z=${player.location.z}, r=2]`, 'tcs_cwp:ender_dagger_punch');
			utils.runCommand(`particle tcs_cwp:teleport_hit_warp ${particleLoc.x} ${particleLoc.y} ${particleLoc.z}`);
		}, 8);

		while (distance < maxDist) {
			dealDamage(player, loc);
			loc.x += dir.x * step;
			loc.z += dir.z * step;
			distance += step;
		}
}

function dealDamage(player, loc = player.location) {
		const entities = player.dimension.getEntities({
			location: loc,
			excludeFamilies: ["utility", "projectile", "furniture"],
			excludeTypes: ["minecraft:item", "minecraft:xp_orb"],
			maxDistance: CONFIG.RANGE,
		});

		if (entities.length <= 1) return;
		for (const entity of entities) {
			if (entity.id === player.id) continue;
			utils.applyDamage(entity, CONFIG.DAMAGE_AMOUNT);
		}
}

export async function onEntityHit(event) {
    const attacker = event.damagingEntity;
    if (!attacker || attacker.typeId !== "minecraft:player") return;


    const target = event.hitEntity;
    if (!target) return;

    const heldItem = attacker
      .getComponent("minecraft:equippable")
      ?.getEquipment(EquipmentSlot.Mainhand);
    if (!heldItem || heldItem.typeId !== "tcs_cwp:ender_dagger") return;

	// Punch animations
	attacker.startItemCooldown("tcs_cwp_special_weapon_punch", 8);
	attacker.playAnimation("animation.tcs_cwp.ender_dagger.hit_tp");

    target.runCommandAsync(`particle tcs_cwp:ender_dagger_on_hit ~ ~1 ~`);
}