import { world, system } from "@minecraft/server";
import * as utils from "../utils";
import * as Vector3 from "../vector3";

const COOLDOWN_CATEGORY = "wand_of_void";
const COOLDOWN_DURATION = 60; // 60 ticks (3s)

const MAX_RANGE = 55;
const STEP = 0.1;

export async function onItemUse(event) {
    const player = event.source;
    const cooldown = player.getItemCooldown(COOLDOWN_CATEGORY);
    if (cooldown > 0) return;

    // Disable player movement and camera
    // player.inputPermissions.movementEnabled = false;
    // player.inputPermissions.cameraEnabled = false;

    // Play third person animation
    utils.runPlayerCommand(player, `playanimation @s animation.goe_bos.player.throw_sword animation.goe_bos.player.fp_attack_v2 0 "v.is_first_person"`);
    utils.runPlayerCommand(player, `playanimation @s animation.goe_bos.player.fp_attack_v2 animation.goe_bos.player.throw_sword 0 "!v.is_first_person"`);
    utils.runPlayerCommand(player, `playanimation @s animation.goe_bos.player.throw_sword animation.player.empty 0 "q.all_animations_finished"`);
    utils.runPlayerCommand(player, `playanimation @s animation.goe_bos.player.fp_attack_v2 animation.player.empty 0 "q.all_animations_finished"`);

    // Delay projectiles
    system.runTimeout(() => {
        shoot(player);
        player.playSound("goe_bos:laser");
        player.dimension.spawnParticle("goe_bos:large_magic_circle_purple", player.location);
    }, 5);

    // Enable camera and movement
    // system.runTimeout(() => {
    //     player.inputPermissions.movementEnabled = true;
    //     player.inputPermissions.cameraEnabled = true;
    // }, 40);

    // Start cooldown
    player.startItemCooldown(COOLDOWN_CATEGORY, COOLDOWN_DURATION);

    damageHeldItem(player);
}

async function shoot(player) {
    const sourcePoint = new Vector3.Vector3(player.location);
    const spawnOffset = Vector3.rotateYAxis(player.getViewDirection(), 30);

    sourcePoint.x += spawnOffset.x;
    sourcePoint.y += 1.5;
    sourcePoint.z += spawnOffset.z;

    let targetPoint = new Vector3.Vector3(sourcePoint).add(new Vector3.Vector3(player.getViewDirection()).multiply(MAX_RANGE));
    const targetBlockHit = player.getBlockFromViewDirection({ maxDistance: MAX_RANGE });
    if (targetBlockHit) targetPoint = new Vector3.Vector3(targetBlockHit.block.location).add(targetBlockHit.faceLocation);

    const targetDistance =  Vector3.distance(sourcePoint, targetPoint);
    const laserDirection = Vector3.unit(Vector3.getVector(sourcePoint, targetPoint));

    let distanceTraveled = 0;

    while (distanceTraveled < targetDistance) {
        distanceTraveled += STEP;
        const spawnPoint = sourcePoint.add(laserDirection.multiply(distanceTraveled));
        const hitEntities = player.dimension.getEntities({
            location: spawnPoint,
            maxDistance: 2.5
        });

        hitEntities.forEach(entity => {
            if (entity === player) return;

            const familyComponent = entity.getComponent("minecraft:type_family");
            if (!familyComponent || (!familyComponent.hasTypeFamily("mob") && !familyComponent.hasTypeFamily("player"))) return;

            try {
                entity.applyDamage(8, { cause: "magic", damagingEntity: player });
                entity.setOnFire(3, false);
            } catch (error) {}
        });

        try {
            player.dimension.spawnParticle("goe_bos:wand_of_void_glow", spawnPoint);
            player.dimension.spawnParticle("goe_bos:wand_of_void_sparks", spawnPoint);
        } catch (error) {}
    }

    try {
        utils.runPlayerCommand(player, "playsound goe_bos:laser_explosion @a[r=20]");
        player.dimension.spawnParticle("goe_bos:wand_of_void_sparks2", targetPoint);
        player.dimension.spawnParticle("goe_bos:wand_of_void_explosion", targetPoint);
    } catch (error) {}
}

function damageHeldItem(player, amount = 1) {
    if (player.getGameMode() === "creative") return;
    
    const inventory = player.getComponent("minecraft:inventory").container;
    const selectedSlot = inventory.getSlot(player.selectedSlotIndex);
    const heldItem = selectedSlot.getItem();
    if (heldItem === undefined) return;

    const durabilityComponent = heldItem.getComponent("minecraft:durability");
    if (durabilityComponent === undefined) return;

    const itemDurability = durabilityComponent.maxDurability;
    const itemDamage = ++durabilityComponent.damage;

    if (itemDamage + 1 === itemDurability) {
        selectedSlot.setItem(undefined);
        return;
    }

    selectedSlot.setItem(heldItem);
}