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

const spears = [
    {name: "pu_sg:hunter_spear", projectile: "pu_sg:hunter_spear_projectile", damage: 6},
    {name: "pu_sg:iron_spear", projectile: "pu_sg:iron_spear_projectile", damage: 8},
    {name: "pu_sg:orange_spear", projectile: "pu_sg:orange_spear_projectile", damage: 9}
];

function getSpear(name) {
    return spears.find(spear => spear.name === name);
}

function getSpearByProjectile(projectile) {
    return spears.find(spear => spear.projectile === projectile);
}

export async function onItemUse(event) {
    const player = event.source;
    const item = event.itemStack;
    if (item && (spears.map(spear => spear.name).includes(item.typeId))) {
        const spear = getSpear(item.typeId);
        const dimension = player.dimension;
        dimension.playSound("pu_sg:spear_throw", player.location);
        //Spawn Projectile
        const direction = Vector3.fromRotation(player.getRotation());
	
        let playerLocation = new Vector3.Vector3(player.location);
        let projectileSpawn = playerLocation.add(Vector3.Up.multiply(2)).add(direction.multiply(2));
    
        const projectile =  dimension.spawnEntity("pu_sg:spear_dummy", {x:projectileSpawn.x, y:projectileSpawn.y, z:projectileSpawn.z});
        const projectileVelocity = direction.multiply(4);
        projectile.applyImpulse({x: projectileVelocity.x, y:projectileVelocity.y, z: projectileVelocity.z});

        const viewDirection = player.getViewDirection();
        const facingLocation = {
            x: playerLocation.x + viewDirection.x,
            y: playerLocation.y + viewDirection.y,
            z: playerLocation.z + viewDirection.z
        };

        ////////////////////////////////////////////////////////////////////////
        const rightDirection = {
            x: -viewDirection.z,
            y: 0, // No vertical offset for right direction
            z: viewDirection.x
        };
        
        // Adjust the projectile spawn position slightly to the right
        const offset = 0.5; // Adjust this value for how far right you want
        const adjustedLocation = {
            x: playerLocation.x + rightDirection.x * offset,
            y: playerLocation.y + 0.7, // Spawn above the player's head
            z: playerLocation.z + rightDirection.z * offset
        };

        const summonCommand = `summon ${spear.projectile} ${adjustedLocation.x} ${adjustedLocation.y} ${adjustedLocation.z} facing ${facingLocation.x} ${facingLocation.y} ${facingLocation.z}`;
        try {
            dimension.runCommand(summonCommand);
            player.getComponent("inventory").container.setItem(player.selectedSlotIndex, null);
        } catch (error) {
            console.warn(error);
            
            return;
        }

        const dummy = dimension.getEntities({
            type: spear.projectile,
            location: playerLocation,
            maxDistance: 5
        })[0];
        let inc = 1;


        const interval = system.runInterval(() => {
            if (!dummy || !dummy.isValid()) {
                system.clearRun(interval);
                return;
            }
            if (!projectile || !projectile.isValid()) {
                system.clearRun(interval);
                return;
            }

            const projectileLocation = projectile.location;
            const facingLocation = {
                x: projectileLocation.x + viewDirection.x,
                y: projectileLocation.y + viewDirection.y,
                z: projectileLocation.z + viewDirection.z
            };
            dummy.teleport({
                x: projectileLocation.x, y: projectileLocation.y, z: projectileLocation.z
            }, {
                facingLocation: facingLocation
            });

            const entitesToDamage = dimension.getEntities({
                location: projectileLocation,
                maxDistance: 2
            });
            for (const entity of entitesToDamage) {
                if (entity.typeId !== "pu_sg:spear_projectile" && entity !== projectile && entity !== player) {
                    entity.applyDamage(spear.damage);
                }
            }

            if (dummy.hasTag("pu_sg_on_ground")) {
                system.runTimeout(() => {
                    projectile?.remove();
                },10);
                system.clearRun(interval);
            }

            if (inc > 100) {
                system.clearRun(interval);
            }
            inc++;
        }, 1);
    }
}


const dimensions = [
    world.getDimension("overworld"),
    world.getDimension("nether"),
    world.getDimension("the_end")
];

export async function onTick() {
    for (const dimension of dimensions) {
        const all_spears = dimension.getEntities();
        for (const spear of all_spears) {
            if (spears.map(spear => spear.projectile).includes(spear.typeId) && spear.hasTag("pu_sg_on_ground")) {
                const currentSpear = getSpearByProjectile(spear.typeId);
                const spearLoc = spear.location;
                const interval = system.run(() => {
                    const players = dimension.getEntities({
                        location: spearLoc,
                        type: "minecraft:player",
                        maxDistance: 2
                    });
                    if (players.length > 0) {
                        const spearItem = new ItemStack(currentSpear.name);
                        system.clearRun(interval);
                        dimension.spawnItem(spearItem, spearLoc);
                        const dummy = dimension.getEntities({
                            location: spearLoc,
                            type: "pu_sg:spear_dummy",
                            maxDistance: 2
                        });
                        dummy[0]?.remove();
                        spear?.remove();
                        return;
                    }
                });
            }
        }
    }
}