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

world.afterEvents.itemCompleteUse.subscribe((eventData) => {
    const player = eventData.source;
    const item = eventData.itemStack;

    if (item.typeId === 'pu_biomes:tree_golem_heart') {
        player.addEffect('strength', 250 * 20, { amplifier: 1 });
        player.addEffect('speed', 250 * 20, { amplifier: 0 });
    
        const radius = 5;
        for (let dx = -radius; dx <= radius; dx++) {
            for (let dz = -radius; dz <= radius; dz++) {
                // Skip some blocks for natural spacing
                if (Math.random() > 0.3) continue;
    
                const x = Math.floor(player.location.x) + dx;
                const y = Math.floor(player.location.y);
                const z = Math.floor(player.location.z) + dz;
    
                // Try placing tallgrass or flowers
                const blockChoice = 'pu_biomes:enchanted_grass';
    
                // Run this as a command to place if the block below is grass
                player.runCommandAsync(`execute if block ${x} ${y - 1} ${z} grass_block run setblock ${x} ${y - 1} ${z} ${blockChoice}`);
                player.runCommandAsync(`execute if block ${x} ${y - 1} ${z} dirt run setblock ${x} ${y - 1} ${z} ${blockChoice}`);
            }
        }
    }  
    
    if (item.typeId === 'pu_biomes:enchanted_mushroom') {
        
        player.addEffect('speed', 10 * 20, { amplifier: 2 });
        player.addEffect('nausea', 10 * 20, { amplifier: 0 });
    }  

    if (item.typeId === 'pu_biomes:tall_enchanted_mushroom') {
        player.addEffect('speed', 20 * 20, { amplifier: 2 });
        player.addEffect('nausea', 20 * 20, { amplifier: 0 });
    }

    if (item.typeId === 'pu_biomes:mummy_bandage') {
        const healthComponent = player.getComponent('health');
        let currentValue = healthComponent.currentValue;
        player.playSound("pu_biomes:bandage");
        healthComponent.setCurrentValue(currentValue + 5);
    }

    if (item.typeId === 'pu_biomes:bandage') {
        const healthComponent = player.getComponent('health');
        player.playSound("pu_biomes:bandage");
        healthComponent.resetToMaxValue();
    }
});

world.afterEvents.itemUse.subscribe((eventData) => {
    const player = eventData.source;
    const item = eventData.itemStack;
    if (item.typeId === 'pu_biomes:wind_core') {
        const viewDir = player.getViewDirection();
    
        // Get only horizontal components and normalize
        const magnitude = Math.sqrt(viewDir.x ** 2 + viewDir.z ** 2);
        const dirX = -viewDir.x / magnitude; // Opposite horizontal direction
        const dirZ = -viewDir.z / magnitude;
    
        const horizontalStrength = 2.5;
        const verticalStrength = 1.0; // Fixed upward boost
    
        player.applyKnockback(dirX, dirZ, horizontalStrength, verticalStrength);

        const headLoc = player.getHeadLocation();
        const viewVector = player.getViewDirection();
        const dimension = player.dimension;

        const startOffset = 1.2;
        const steps = 2;
        const speed = 0.5;

        let start;

        // If looking almost straight down
        if (viewVector.y < -0.79) {
            // Spawn below the player
            start = player.location;
        } else {
            // Normal start in front of view
            start = {
                x: headLoc.x + viewVector.x * startOffset,
                y: headLoc.y + viewVector.y * startOffset,
                z: headLoc.z + viewVector.z * startOffset,
            };
        }

        let i = 0;
        const intervalId = system.runInterval(() => {
            if (!player.isValid()) {
                system.clearRun(intervalId);
                return;
            }

            const pos = {
                x: start.x + viewVector.x * i * speed,
                y: start.y + viewVector.y * i * speed,
                z: start.z + viewVector.z * i * speed,
            };
            try {
                dimension.spawnParticle("pu_biomes:wind_core", pos);
            } catch (error) {
            }
            i++;

            if (i > steps) {
                system.clearRun(intervalId);
            }
        }, 1);

        player.playSound("pu_biomes:wind");
        player.runCommand(`clear @s pu_biomes:wind_core 0 1`);
    }

    if (item.typeId === 'pu_biomes:unicorn_horn') {

        try {
            const cooldownComponent = item.getComponent("minecraft:cooldown");
            if (cooldownComponent) {
               const cooldownTicks = cooldownComponent.getCooldownTicksRemaining(player);
                if (cooldownTicks > 0) {
                    return;
                }
                
            }
            player.playSound("pu_biomes:unicorn_horn");
            // Handle durability
            if (item.getComponent("minecraft:durability").damage < (item.getComponent("minecraft:durability").maxDurability - 1)) {
                const newItem = item.clone();
                newItem.getComponent("minecraft:durability").damage = item.getComponent("minecraft:durability").damage + 1;
                player.getComponent("inventory").container.setItem(player.selectedSlotIndex, newItem);
                const cooldownComponent = newItem.getComponent("minecraft:cooldown");
                if (cooldownComponent) {
                    cooldownComponent.startCooldown(player);
                }
            } else {
                player.playSound("random.break");
                player.getComponent("inventory").container.setItem(player.selectedSlotIndex, null);
            }
        } catch (error) {
            
        }
    }

    if (item.typeId === "pu_biomes:fireball") {
        const dimension = player.dimension; 
        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_biomes:dummy_projectile", {x:projectileSpawn.x, y:projectileSpawn.y, z:projectileSpawn.z});
        const projectileVelocity = direction.multiply(1.5);
        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 pu_biomes:fireball_projectile ${adjustedLocation.x} ${adjustedLocation.y} ${adjustedLocation.z} facing ${facingLocation.x} ${facingLocation.y} ${facingLocation.z}`;
        try {
            dimension.runCommand(summonCommand);
            if (item.typeId === "pu_biomes:fireball") {
                player.runCommand("clear @s pu_biomes:fireball 0 1");
            }
        } catch (error) {
            console.warn(error);
            
            return;
        }
        player.playSound("mob.ghast.fireball");

        const dummy = dimension.getEntities({
            type: "pu_biomes:fireball_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()) {
                const loc = dummy?.location;
                dummy?.dimension.createExplosion(loc, 2);
                const topBlock = dummy?.dimension.getTopmostBlock(loc, loc.y);
                try {
                    if (topBlock && topBlock.location.y < loc.y) {

                        const directions = [
                            topBlock.above(),
                            topBlock.north(),
                            topBlock.south(),
                            topBlock.west(),
                            topBlock.east()
                        ];
                        
                        function setFireIfAir(b) {
                            if (b?.isAir) {
                                b.setPermutation(BlockPermutation.resolve("minecraft:fire"));
                            }
                        }
                        
                        for (const dir of directions) {
                            setFireIfAir(dir);
                        }
                        
                        for (const dir of directions) {
                            if (!dir?.isAir) {
                                const adjacents = [
                                    dir.above(),
                                    dir.north(),
                                    dir.south(),
                                    dir.west(),
                                    dir.east()
                                ];
                                for (const adjacent of adjacents) {
                                    setFireIfAir(adjacent);
                                }
                            }
                        }
                    }
                } catch (error) {
                }
                system.runTimeout(() => { if (dummy && dummy.isValid()) dummy?.remove(); }, 7);
                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
            });

            if (inc > 100) {
                dummy?.dimension.createExplosion(dummy?.location, 5);
                dummy?.remove();
                system.clearRun(interval);
                return;
            }
            inc++;
        }, 1);
    }

    if (item.typeId === "pu_biomes:staff") {
        try {
            const dimension = player.dimension; 
            const direction = Vector3.fromRotation(player.getRotation());
    	
            let playerLocation = new Vector3.Vector3(player.location);
            let projectileSpawn = playerLocation.add(Vector3.Up.multiply(1.5)).add(direction.multiply(1.5));
        
            const projectile =  dimension.spawnEntity("pu_biomes:staff_projectile", {x:projectileSpawn.x, y:projectileSpawn.y, z:projectileSpawn.z});
            const projectileVelocity = direction.multiply(1.3);
            projectile.applyImpulse({x: projectileVelocity.x, y:projectileVelocity.y, z: projectileVelocity.z});

            const target = player.getEntitiesFromViewDirection({ maxDistance: 3 });
            const damage = 8;
            for (const e of target) {
                const entity = e.entity;
                if(entity.typeId === "minecraft:item") continue;
                if (!entity || !entity.isValid()) continue;
                if (entity || entity.isValid()) entity.applyDamage(damage, { damagingEntity: player, cause: EntityDamageCause.magic });
            }
    
            player.playSound("pu_biomes:staff");
    
            // Handle durability
            if (item.getComponent("minecraft:durability").damage < (item.getComponent("minecraft:durability").maxDurability - 1)) {
                const newItem = item.clone();
                newItem.getComponent("minecraft:durability").damage = item.getComponent("minecraft:durability").damage + 1;
                player.getComponent("inventory").container.setItem(player.selectedSlotIndex, newItem);
                const cooldownComponent = newItem.getComponent("minecraft:cooldown");
                if (cooldownComponent) {
                    cooldownComponent.startCooldown(player);
                }
            } else {
                player.playSound("random.break");
                player.getComponent("inventory").container.setItem(player.selectedSlotIndex, null);
            }
        } catch (error) {
            
        }
    }
});
let tickCounter = 0;
const invisibilityCloakRun = system.runInterval(() => {
    tickCounter = tickCounter + 1;
    try {
        const players = world.getDimension("overworld").getPlayers();
        for (const player of players) {
            const equippable = player.getComponent('equippable');
            if(equippable){
                const chest = equippable.getEquipment(EquipmentSlot.Chest);
                if(chest){
                    if(chest.typeId === "pu_biomes:invisibility_cloak" && player.isSneaking){
                        player.addEffect('invisibility', 20, { amplifier: 2 , showParticles: false});
                    } else {
                        player.removeEffect('invisibility');
                    }

                    if(chest.typeId === "pu_biomes:owl_wings") {
                        if (player.isJumping) {
                            player.addEffect("levitation", 20, {amplifier: 1, showParticles: false});
                            if ( tickCounter % 100 === 0) {
                                // Handle durability
                                if (chest.getComponent("minecraft:durability").damage < (chest.getComponent("minecraft:durability").maxDurability - 1)) {
                                    const newItem = chest.clone();
                                    newItem.getComponent("minecraft:durability").damage = chest.getComponent("minecraft:durability").damage + 1;
                                    equippable.setEquipment(EquipmentSlot.Chest, newItem);
                                } else {
                                    player.playSound("random.break");
                                    equippable.setEquipment(EquipmentSlot.Chest, undefined);
                                }
                            }
                        } else {
                            if (!player.isOnGround) {
                                player.addEffect("slow_falling", 20, {amplifier: 1, showParticles: false});
                            }
                        } 
                    }
                }

                if(isHoldingBook(equippable)) {
                    if (!player.hasTag("pu_biomes_guidebook")) {
                        player.addTag("pu_biomes_guidebook");
                        player.playSound("pu_biomes:guide_book_open");
                    }
                } else if (player.hasTag("pu_biomes_guidebook")) {
                    player.removeTag("pu_biomes_guidebook");
                    player.playSound("pu_biomes:guide_book_close");
                }
                    }
                }
    } catch (error) {
    }
}, 10);

function isHoldingBook(equipment){
	let itemInHand = equipment.getEquipment(EquipmentSlot.Mainhand);
	if(itemInHand === undefined) return false;
    if(itemInHand.typeId === "pu_biomes:info_book" ) {
        return true;
    }
}