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

function hasItemInFilter(item, id) {
    return id == item.typeId;
}

function recipeCompleted(entity, inv) {
    let noneFilters = 0
    let greenFilters = 0
    for (let i = 0; i < inv.size; i++) {
        let filter = entity.getProperty(`vtng_rt:slot${i}`)
        if (filter == 'none') noneFilters++;
        if (filter == 'green') greenFilters++
    }
    return greenFilters == (9 - noneFilters)
}

function setItemOnSlotAvailable(crafter, inv, roboticEntity, handType, itemPlace) {
    for (let i = 0; i < inv.size; i++) {
        let slot = inv.getItem(i)
        let itemInFilter = crafter.getDynamicProperty(`vtng_rt:slot${i}`)
        let invRoboticArm = roboticEntity.getComponent('inventory').container
        if (hasItemInFilter(itemPlace.typeId, itemInFilter)) {
            if (slot && (slot.amount == slot.maxAmount || slot.amount == 1)) continue;
            let newItem = itemPlace.clone()
            newItem.amount = 1
            inv.setItem(i, newItem)
            if (itemPlace.amount > 1) {
                itemPlace.amount--
                invRoboticArm.setItem(0, itemPlace)
            } else {
                roboticEntity.runCommand(`replaceitem entity @s slot.weapon.${handType} 0 air`)
                invRoboticArm.setItem(0,)
            }
            break;
        }
    }
}

mc.world.beforeEvents.worldInitialize.subscribe(data => {
    data.blockComponentRegistry.registerCustomComponent('vtng_rt:mechanical_crafter', {
        onPlace: (({ block, dimension }) => {
            let states = block.permutation.getAllStates()
            const offsets = {
                north: [
                    { x: 0, z: 0.25, tags: ['slot:0', 'slot:1'] }, // Base de referência
                    { x: -0.25, z: 0.25, tags: ['slot:2'] },
                    { x: 0, z: 0, tags: ['slot:3', 'slot:4'] },
                    { x: -0.25, z: 0, tags: ['slot:5'] },
                    { x: 0, z: -0.25, tags: ['slot:6', 'slot:7'] },
                    { x: -0.25, z: -0.25, tags: ['slot:8'] }
                ],
                south: [
                    { x: 0, z: -0.25, tags: ['slot:0', 'slot:1'] },
                    { x: 0.25, z: -0.25, tags: ['slot:2'] },
                    { x: 0, z: 0, tags: ['slot:3', 'slot:4'] },
                    { x: 0.25, z: 0, tags: ['slot:5'] },
                    { x: 0, z: 0.25, tags: ['slot:6', 'slot:7'] },
                    { x: 0.25, z: 0.25, tags: ['slot:8'] }
                ],
                east: [
                    { x: -0.25, z: 0, tags: ['slot:0', 'slot:1'] },
                    { x: -0.25, z: -0.25, tags: ['slot:2'] },
                    { x: 0, z: 0, tags: ['slot:3', 'slot:4'] },
                    { x: 0, z: -0.25, tags: ['slot:5'] },
                    { x: 0.25, z: 0, tags: ['slot:6', 'slot:7'] },
                    { x: 0.25, z: -0.25, tags: ['slot:8'] }
                ],
                west: [
                    { x: 0.25, z: 0, tags: ['slot:0', 'slot:1'] },
                    { x: 0.25, z: 0.25, tags: ['slot:2'] },
                    { x: 0, z: 0, tags: ['slot:3', 'slot:4'] },
                    { x: 0, z: 0.25, tags: ['slot:5'] },
                    { x: -0.25, z: 0, tags: ['slot:6', 'slot:7'] },
                    { x: -0.25, z: 0.25, tags: ['slot:8'] }
                ]
            };

            let directionToNumber = {
                'north': 0,
                'south': 180,
                'east': 90,
                'west': 270
            }

            racoAPI.setPermutation(block, 'vtng_rt:is_invisible', true)
            let loc = block.center()
            loc.y -= 0.5
            dimension.spawnEntity('vtng_rt:mechanical_crafter', loc).setProperty('vtng_rt:rotation', directionToNumber[states['minecraft:cardinal_direction']]);

            offsets[states['minecraft:cardinal_direction']].slice(0, 6).forEach(offset => {
                let entity = dimension.spawnEntity('vtng_rt:mechanical_crafter_entity', {
                    x: block.center().x + offset.x,
                    y: block.y + 1,
                    z: block.center().z + offset.z
                });
                entity.setProperty('vtng_rt:rotation', directionToNumber[states['minecraft:cardinal_direction']]);
                offset.tags.forEach(tag => entity.addTag(tag));
                if (!['2', '5', '8'].includes(offset.tags[0].split(':')[1])) {
                }
            });
        }),
        onPlayerDestroy: (({ block, dimension }) => {
            let entities = dimension.getEntities({ location: block.center(), maxDistance: 1, type: 'vtng_rt:mechanical_crafter_entity' })
            for (let entity of entities) {
                if (entity.typeId == 'vtng_rt:mechanical_crafter_entity') entity.remove();

            }

        }),
        onPlayerInteract: (({ faceLocation, block, dimension, player }) => {
            let equippable = player.getComponent('equippable')
            let itemHold = equippable.getEquipment('Mainhand')
            let states = block.permutation.getAllStates()
            let X = (faceLocation.x - block.x).toFixed(2)
            let Z = (faceLocation.z - block.z).toFixed(2)

            //console.warn('x:', X, 'z:', Z, states['minecraft:cardinal_direction'])

            let directionsPos = {
                'north': [
                    { xMin: 0.68, xMax: 0.87, zMin: 0.68, zMax: 0.87 }, // 0
                    { xMin: 0.44, xMax: 0.63, zMin: 0.68, zMax: 0.87 }, // 1
                    { xMin: 0.19, xMax: 0.38, zMin: 0.68, zMax: 0.87 }, // 2
                    { xMin: 0.68, xMax: 0.87, zMin: 0.44, zMax: 0.63 }, // 3
                    { xMin: 0.44, xMax: 0.63, zMin: 0.44, zMax: 0.63 }, // 4
                    { xMin: 0.19, xMax: 0.38, zMin: 0.44, zMax: 0.63 }, // 5
                    { xMin: 0.68, xMax: 0.87, zMin: 0.17, zMax: 0.37 }, // 6
                    { xMin: 0.44, xMax: 0.63, zMin: 0.17, zMax: 0.37 }, // 7
                    { xMin: 0.19, xMax: 0.38, zMin: 0.17, zMax: 0.37 }  // 8
                ],
                'south': [
                    { xMin: 0.19, xMax: 0.38, zMin: 0.13, zMax: 0.32 }, // 0
                    { xMin: 0.44, xMax: 0.63, zMin: 0.13, zMax: 0.32 }, // 1
                    { xMin: 0.68, xMax: 0.87, zMin: 0.13, zMax: 0.32 }, // 2
                    { xMin: 0.19, xMax: 0.38, zMin: 0.36, zMax: 0.56 }, // 3
                    { xMin: 0.44, xMax: 0.63, zMin: 0.36, zMax: 0.56 }, // 4
                    { xMin: 0.68, xMax: 0.87, zMin: 0.36, zMax: 0.56 }, // 5
                    { xMin: 0.19, xMax: 0.38, zMin: 0.60, zMax: 0.80 }, // 6
                    { xMin: 0.44, xMax: 0.63, zMin: 0.60, zMax: 0.80 }, // 7
                    { xMin: 0.68, xMax: 0.87, zMin: 0.60, zMax: 0.80 }  // 8
                ],
                'east': [
                    { xMin: 0.13, xMax: 0.32, zMin: 0.68, zMax: 0.87 }, // 0
                    { xMin: 0.13, xMax: 0.32, zMin: 0.44, zMax: 0.63 }, // 1
                    { xMin: 0.13, xMax: 0.32, zMin: 0.19, zMax: 0.38 }, // 2
                    { xMin: 0.36, xMax: 0.56, zMin: 0.68, zMax: 0.87 }, // 3
                    { xMin: 0.36, xMax: 0.56, zMin: 0.44, zMax: 0.63 }, // 4
                    { xMin: 0.36, xMax: 0.56, zMin: 0.19, zMax: 0.38 }, // 5
                    { xMin: 0.60, xMax: 0.80, zMin: 0.68, zMax: 0.87 }, // 6
                    { xMin: 0.60, xMax: 0.80, zMin: 0.44, zMax: 0.63 }, // 7
                    { xMin: 0.60, xMax: 0.80, zMin: 0.19, zMax: 0.38 }  // 8
                ],
                'west': [
                    { xMin: 0.68, xMax: 0.87, zMin: 0.13, zMax: 0.32 }, // 0
                    { xMin: 0.68, xMax: 0.87, zMin: 0.36, zMax: 0.56 }, // 1
                    { xMin: 0.68, xMax: 0.87, zMin: 0.60, zMax: 0.80 }, // 2
                    { xMin: 0.44, xMax: 0.63, zMin: 0.13, zMax: 0.32 }, // 3
                    { xMin: 0.44, xMax: 0.63, zMin: 0.36, zMax: 0.56 }, // 4
                    { xMin: 0.44, xMax: 0.63, zMin: 0.60, zMax: 0.80 }, // 5
                    { xMin: 0.19, xMax: 0.38, zMin: 0.13, zMax: 0.32 }, // 6
                    { xMin: 0.19, xMax: 0.38, zMin: 0.36, zMax: 0.56 }, // 7
                    { xMin: 0.19, xMax: 0.38, zMin: 0.60, zMax: 0.80 }  // 8
                ]
            };

            if (itemHold?.hasTag('vtng_rt:is_tool') || itemHold?.typeId.includes('exchange_rod')) return player.sendMessage({translate: 'vtng_rt.crafter_unsupported_item.warn'});

            let itemsFake = ["shovel", "sword", "axe", "hoe", "mace", "bow", "trident", "pointed_dripstone", "fishing_rod", "stick", "spyglass", "breeze_rod", "blaze_rod"]

            directionsPos[states['minecraft:cardinal_direction']].forEach((slot, index) => {
                if (X >= slot.xMin && X <= slot.xMax && Z >= slot.zMin && Z <= slot.zMax) {
                    let [entity] = dimension.getEntities({ type: 'vtng_rt:mechanical_crafter_entity', closest: 1, location: block.center(), tags: [`slot:${index}`] })
                    let [crafterEntity] = dimension.getEntities({ type: 'vtng_rt:mechanical_crafter', closest: 1, location: block.center(), maxDistance: 0.75 })
                    let inv = crafterEntity?.getComponent('inventory')?.container
                    let filter = crafterEntity.getProperty(`vtng_rt:slot${index}`)

                    if ([1, 4, 7, 2, 5, 8].includes(index)) {
                        let slot = inv.getItem(index)
                        if (!itemHold) {
                            if (player.isSneaking && filter == 'green') {
                                if (slot) entity.dimension.spawnItem(slot, block.above().bottomCenter()), inv.setItem(index,);
                            } else {
                                if (slot) entity.dimension.spawnItem(slot, block.above().bottomCenter()), inv.setItem(index,);
                                entity?.runCommand(`replaceitem entity @s slot.weapon.mainhand 0 air`)
                                crafterEntity.setProperty(`vtng_rt:slot${index}`, 'none')
                                crafterEntity.setDynamicProperty(`vtng_rt:slot${index}`, null);
                            }
                        } else {
                            if (racoAPI.itemIsBlock(block, itemHold)) {
                                entity.setProperty('vtng_rt:type_right', 1)
                            } else entity.setProperty('vtng_rt:type_right', 0)

                            if (slot && itemHold.typeId != crafterEntity.getDynamicProperty(`vtng_rt:slot${index}`)) entity.dimension.spawnItem(slot, block.above().bottomCenter()), inv.setItem(index,)

                            crafterEntity.setProperty(`vtng_rt:slot${index}`, 'red')
                            crafterEntity.setDynamicProperty(`vtng_rt:slot${index}`, itemHold.typeId)

                            entity?.runCommand(`replaceitem entity @s slot.weapon.mainhand 0 ${itemsFake.some(item => itemHold.typeId.endsWith(item)) ? 'vtng_rt:fake_' + itemHold.typeId.split(':')[1] : itemHold.typeId}`)
                        }
                    }
                    if ([0, 3, 6].includes(index)) {
                        let slot = inv.getItem(index)
                        if (!itemHold) {
                            if (player.isSneaking && filter == 'green') {
                                if (slot) entity.dimension.spawnItem(slot, block.above().bottomCenter()), inv.setItem(index,);
                            } else {
                                if (slot) entity.dimension.spawnItem(slot, block.above().bottomCenter()), inv.setItem(index,);
                                entity?.runCommand(`replaceitem entity @s slot.weapon.offhand 0 air`)
                                crafterEntity.setProperty(`vtng_rt:slot${index}`, 'none')
                                crafterEntity.setDynamicProperty(`vtng_rt:slot${index}`, null);
                            }
                        } else {
                            if (racoAPI.itemIsBlock(block, itemHold)) {
                                entity.setProperty('vtng_rt:type_left', 1)
                            } else entity.setProperty('vtng_rt:type_left', 0)

                            if (slot && itemHold.typeId != crafterEntity.getDynamicProperty(`vtng_rt:slot${index}`)) entity.dimension.spawnItem(slot, block.above().bottomCenter()), inv.setItem(index,)

                            crafterEntity.setProperty(`vtng_rt:slot${index}`, 'red')
                            crafterEntity.setDynamicProperty(`vtng_rt:slot${index}`, itemHold.typeId)

                            entity?.runCommand(`replaceitem entity @s slot.weapon.offhand 0 ${itemsFake.some(item => itemHold.typeId.endsWith(item)) ? 'vtng_rt:fake_' + itemHold.typeId.split(':')[1] : itemHold.typeId}`)
                        }
                    }
                }
            });
        })
    })
})

mc.system.afterEvents.scriptEventReceive.subscribe(data => {
    if (data.id == 'vtng_rt:mechanical_crafter') {
        let entity = data.sourceEntity // entity.typeId é esse
        let block = entity.dimension.getBlock(entity.location)
        let direction = block.permutation.getState('minecraft:cardinal_direction')
        let state = entity.getProperty('vtng_rt:redstone_active')
        let faces = ['north', 'south', 'west', 'east', 'above']
        let inv = entity.getComponent('inventory').container
        const hasPower = hasRedstonePower(block, ['north', 'south', 'west', 'east', 'below'], true)

        for (let i = 0; i < 9; i++) {
            let slot = inv.getItem(i)
            if (!slot && entity.getDynamicProperty(`vtng_rt:slot${i}`)) {
                entity.setProperty(`vtng_rt:slot${i}`, 'red')
            }
            if (!slot && !entity.getDynamicProperty(`vtng_rt:slot${i}`)) {
                entity.setProperty(`vtng_rt:slot${i}`, 'none')
            }
            if (slot && entity.getDynamicProperty(`vtng_rt:slot${i}`)) {
                entity.setProperty(`vtng_rt:slot${i}`, 'green')
            }
        }

        if (hasPower == undefined && state != 0) {
            entity.setProperty('vtng_rt:redstone_active', 0)
        }

        if (hasPower == true && state == 0) {
            entity.runCommand(`setblock ${block.x} -63 ${block.z} crafter ["orientation"="up_north"]`)
            entity.setProperty('vtng_rt:redstone_active', 2)
            for (let i = 0; i < inv.size; i++) {
                let slot = inv.getItem(i)
                if (!slot) continue;
                entity.runCommand(`replaceitem block ${block.x} -63 ${block.z} slot.container ${i} ${slot.typeId}`)
            }
            entity.runCommand(`setblock ${block.x} -62 ${block.z} air`)

            mc.system.runTimeout(() => {
                entity.runCommand(`setblock ${block.x} -64 ${block.z} redstone_block`)
                mc.system.runTimeout(() => {
                    let [itemOutput] = entity.dimension.getEntities({ type: 'minecraft:item', location: { x: block.x, y: -62, z: block.z, maxDistance: 2 } })
                    if (itemOutput && recipeCompleted(entity, inv)) {
                        for (let i = 0; i < inv.size; i++) {
                            let slot = inv.getItem(i)
                            if (!slot) continue;
                            entity.runCommand(`replaceitem block ${block.x} -63 ${block.z} slot.container ${i} air`)
                            entity.runCommand(`replaceitem entity @s slot.inventory ${i} air`)
                        }
                        // Drop System --> 
                        block.dimension.playSound("block.click", block.center())
                        let loc = block.center()
                        if (direction == 'north') loc = racoAPI.operationWithVectorMINUS(loc, 0, 0, 0.15)
                        if (direction == 'south') loc = racoAPI.operationWithVectorPLUS(loc, 0, 0, 0.15)
                        if (direction == 'west') loc = racoAPI.operationWithVectorMINUS(loc, 0.15, 0, 0)
                        if (direction == 'east') loc = racoAPI.operationWithVectorPLUS(loc, 0.15, 0, 0)
                        try {
                            let itemSpawned = entity.dimension.spawnItem(itemOutput.getComponent('item').itemStack, block[direction]().bottomCenter())
                            let impulseLoc = racoAPI.calculateRelativeVector(racoAPI.blockFloorCenter(block), loc)
                            entity.dimension.spawnParticle('vtng_rt:crafter_smoke_' + racoAPI.invertFace(direction), block.center())
                            entity.setProperty('vtng_rt:redstone_active', 1)
                            mc.system.runTimeout(() => {entity.setProperty('vtng_rt:redstone_active', 2)},5)
                            mc.system.runTimeout(() => { try { itemSpawned.applyImpulse(impulseLoc) } catch (error) { } }, 1)
                        } catch (error) { }
                        itemOutput.remove()

                    }
                    entity.runCommand(`setblock ${block.x} -63 ${block.z} dirt`)
                    entity.runCommand(`setblock ${block.x} -64 ${block.z} bedrock`)
                    entity.runCommand(`setblock ${block.x} -62 ${block.z} dirt`)
                }, 8)
            }, 1)
        }

        for (const face of faces) {
            if (face != direction) {
                const hopper = block[face]()
                if (hopper.typeId == 'minecraft:hopper') {
                    const facing = racoAPI.blockFaceToDirection(numToDirection(hopper.permutation.getState('facing_direction')))
                    if (racoAPI.invertFace(facing) == face) {
                        let hopperInv = hopper.getComponent('inventory').container
                        hopper: for (let i = 0; i < hopperInv.size; i++) {
                            let hopperSlot = hopperInv.getItem(i)
                            if (hopperSlot) {
                                for (let j = 0; j < inv.size; j++) {
                                    let slot = inv.getItem(j)

                                    if (hasItemInFilter(hopperSlot, entity.getDynamicProperty(`vtng_rt:slot${j}`))) {
                                        if (slot && (slot.amount == slot.maxAmount || slot.amount == 1)) continue;
                                        let hopperItemNew = hopperSlot.clone()
                                        hopperItemNew.amount = 1
                                        inv.setItem(j, hopperItemNew)
                                        if (hopperSlot.amount > 1) {
                                            hopperSlot.amount--
                                            hopperInv.setItem(i, hopperSlot)
                                        } else {
                                            hopperInv.setItem(i,)
                                        }
                                        entity.setProperty(`vtng_rt:slot${j}`, 'green')
                                        break hopper;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    }
})

mc.world.beforeEvents.playerInteractWithBlock.subscribe(data => {
    const { block, itemStack, player, blockFace, isFirstEvent } = data
    let isBlock = false

    if (block.typeId == 'vtng_rt:mechanical_crafter' && player.isSneaking && blockFace == 'Up' && block.above().isAir && isFirstEvent) {
        mc.system.run(() => {
            try {
                isBlock = block.dimension.runCommand(`setblock ${block.x} -64 ${block.z} ${itemStack.typeId}`).successCount > 0
            } catch (e) { }
            if (isBlock) {
                block.dimension.runCommand(`setblock ${block.x} ${block.y + 1} ${block.z} ${itemStack.typeId}`)
                block.dimension.runCommand(`setblock ${block.x} -64 ${block.z} bedrock`)

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

function numToDirection(number){
    if (number == 0) return "below"
    if (number == 1) return "above"
    if (number == 2) return "north"
    if (number == 3) return "south"
    if (number == 4) return "west"
    if (number == 5) return "east"
}