import * as mc from "@minecraft/server";
import * as racoAPI from "./raco-API"

function createRandomOrder(length) {
    const indices = Array.from({ length }, (_, i) => i);

    const [first, ...rest] = indices;
    const shuffled = rest.sort(() => Math.random() - 0.5);
    return [first, ...shuffled];
}

mc.world.beforeEvents.itemUseOn.subscribe((data) => {
    const { source: player, itemStack, block, blockFace, isFirstEvent } = data

    if (itemStack.typeId == 'vtng_rt:exchange_rod') {
        mc.system.run(() => {
            if (!player.isSneaking) {
                if (isFirstEvent) {
                    if (block.typeId == 'minecraft:bedrock' || block.typeId.includes('vtng_rt')) return;
                    exchangeRod(block, itemStack, block.dimension, blockFace, player, true)
                }
            } else {
                if (block.typeId == 'minecraft:bedrock' || block.typeId.includes('vtng_rt')) return;
                let equippable = player.getComponent('equippable')
                itemStack.setLore([`§r§8${block.typeId}`])
                equippable.setEquipment('Mainhand', itemStack)
            }
        })

    }
});

mc.system.runInterval(() => {
    for (const player of mc.world.getAllPlayers()) {
        if (player) {
            let itemHold = player.getComponent('equippable').getEquipment('Mainhand')
            if (itemHold?.typeId == 'vtng_rt:exchange_rod' && itemHold.getLore()[0]) {
                let viewDirection = player.getBlockFromViewDirection({ maxDistance: 9 })
                if (!viewDirection) return;
                if (viewDirection.block.typeId == 'minecraft:bedrock' || viewDirection.block.typeId.includes('vtng_rt')) return;
                exchangeRod(viewDirection.block, itemHold, viewDirection.block.dimension, viewDirection.face, player, false)
            }
        }
    }

}, 1)

function exchangeRod(block, itemStack, dimension, direction, player, place) {
    const blockId = itemStack.getLore()[0]?.replaceAll('§r§8', '');
    let index = 0;

    if (!blockId && place) return player.sendMessage({ translate: 'vntg_rt.exchange_rod_block_invalid.warn' });

    const blocksToReplace = [];

    let dxStart = 0, dxEnd = 0, dzStart = 0, dzEnd = 0, dyStart = 0, dyEnd = 0;

    switch (direction) {
        case "Up":
        case "Down":
            dxStart = -3;
            dxEnd = 3;
            dzStart = -3;
            dzEnd = 3;
            dyStart = 0;
            dyEnd = 0;
            break;

        case "South":
            dxStart = -3;
            dxEnd = 3;
            dyStart = -1;
            dyEnd = 5;
            break;

        case "North":
            dxStart = -3;
            dxEnd = 3;
            dyStart = -1;
            dyEnd = 5;
            break;

        case "West":
            dzStart = -3;
            dzEnd = 3;
            dyStart = -1;
            dyEnd = 5;
            break;

        case "East":
            dzStart = -3;
            dzEnd = 3;
            dyStart = -1;
            dyEnd = 5;
            break;
    }

    for (let dx = dxStart; dx <= dxEnd; dx++) {
        for (let dz = dzStart; dz <= dzEnd; dz++) {
            for (let dy = dyStart; dy <= dyEnd; dy++) {
                const targetX = block.location.x + dx;
                const targetY = block.location.y + dy;
                const targetZ = block.location.z + dz;

                const targetBlock = dimension.getBlock({ x: targetX, y: targetY, z: targetZ });

                if (targetBlock && targetBlock.typeId === block.typeId && targetBlock.typeId !== blockId) {
                    blocksToReplace.push({ x: targetX, y: targetY, z: targetZ });
                }
            }
        }
    }

    if (!place) {
        for (let coord of blocksToReplace) {
            let thisBlock = dimension.getBlock(coord)
            let center = thisBlock.center()
            center.y -= 0.5
            let [entity] = dimension.getEntitiesAtBlockLocation(center)
            if (!entity) dimension.spawnEntity('vtng_rt:exchange_rod_selection', center);
        }
    }

    if (place) {
        const randomOrder = createRandomOrder(blocksToReplace.length);
        const replaceNextBlock = () => {
            if (index >= blocksToReplace.length) return;

            const nextIndex = randomOrder[index];
            const { x, y, z } = blocksToReplace[nextIndex];
            let hasItem = false;

            let inv = player.getComponent('inventory').container;
            for (let i = 0; i < inv.size; i++) {
                let slot = inv.getItem(i);
                if (slot?.typeId == blockId) {
                    hasItem = true;
                    break;
                }
            }

            if (hasItem && player.getGameMode() != 'creative') {
                player.runCommand(`clear @s ${blockId} 0 1`);
            }

            if (!hasItem && player.getGameMode() != 'creative') {
                return player.sendMessage({ translate: 'vntg_rt.exchange_rod_block_missing.warn' });
            }

            dimension.runCommandAsync(`setblock ${x} ${y} ${z} air destroy`).then(() => {
                let [entityItem] = dimension.getEntities({ type: 'minecraft:item', location: { x: x, y: y, z: z }, maxDistance: 2 })
                if (entityItem && player.getGameMode() == 'creative') {
                    entityItem.remove()
                }
                dimension.runCommand(`execute positioned ${x} ${y} ${z} run kill @e[type=xp_orb,r=1]`);
                dimension.runCommand(`setblock ${x} ${y} ${z} ${blockId}`);
            })

            index++;
            mc.system.runTimeout(replaceNextBlock, 2);
        };
        replaceNextBlock();
    }

}