import { world, BlockLocation, ItemStack, ItemTypes, Location } from "@minecraft/server"

const dimensions = ['overworld', 'nether', 'the_end']
let admin = false

world.events.tick.subscribe(t => {
    if (t.currentTick % 4 === 0) {
        for (const player of world.getPlayers()) {
            const item = player.getComponent("inventory").container.getItem(player.selectedSlot)
            const { x, y, z } = player.location
            try {
                const block = world.getDimension(player.dimension.id).getBlock(new BlockLocation(Math.floor(x), Math.floor(y + 1.5), Math.floor(z))).typeId
                if (block === 'effect99:conveyor_tube_up' || block === 'effect99:conveyor_tube_down' || block === 'effect99:conveyor_tube_station' || block === 'effect99:conveyor_tube_station_up' || block === 'effect99:conveyor_tube_up_off' || block === 'effect99:conveyor_tube_down_off') {
                    player.runCommandAsync('playanimation @s animation.conveyor.tube')
                } else if (block === 'effect99:conveyor_tube_north' || block === 'effect99:conveyor_tube_south' || block === 'effect99:conveyor_tube_east' || block === 'effect99:conveyor_tube_west' || block === 'effect99:conveyor_tube_north_off' || block === 'effect99:conveyor_tube_south_off' || block === 'effect99:conveyor_tube_east_off' || block === 'effect99:conveyor_tube_west_off') {
                    player.runCommandAsync('playanimation @s animation.conveyor.tube_sides')
                }
                if (player.isSneaking && world.getDimension(player.dimension.id).getBlock(new BlockLocation(Math.floor(x), Math.floor(y - 1), Math.floor(z))).hasTag('not_full_storage')) {
                    const permutation = world.getDimension(player.dimension.id).getBlock(new BlockLocation(Math.floor(x), Math.floor(y - 1), Math.floor(z))).permutation
                    permutation.getProperty('xp:level').value++
                    world.getDimension(player.dimension.id).getBlock(new BlockLocation(Math.floor(x), Math.floor(y - 1), Math.floor(z))).setPermutation(permutation)
                    player.runCommandAsync('xp -1l @s')
                }
            } catch (e) { }

            try {
                const itemId = item.typeId
                if (!admin) {
                    if (itemId === 'effect99:powered_cable') give(player, 'effect99:power_cable')
                    else if (itemId === 'effect99:powered_cable_red') give(player, 'effect99:power_cable_red')
                    else if (itemId === 'effect99:powered_cable_blue') give(player, 'effect99:power_cable_blue')
                    else if (itemId === 'effect99:powered_cable_green') give(player, 'effect99:power_cable_green')
                    else if (itemId === 'effect99:powered_reinforced_cable') give(player, 'effect99:reinforced_cable')
                    else if (itemId === 'effect99:powered_reinforced_cable_red') give(player, 'effect99:reinforced_cable_red')
                    else if (itemId === 'effect99:powered_reinforced_cable_blue') give(player, 'effect99:reinforced_cable_blue')
                    else if (itemId === 'effect99:powered_reinforced_cable_green') give(player, 'effect99:reinforced_cable_green')
                    else if (itemId === 'effect99:powered_cable_controller') give(player, 'effect99:power_cable_controller')
                    else if (itemId === 'effect99:quarry_structure') give(player, 'effect99:small_quarry_in_box')
                    else if (itemId === 'effect99:medium_quarry_structure') give(player, 'effect99:medium_quarry_in_box')
                    else if (itemId === 'effect99:largue_quarry_structure') give(player, 'effect99:largue_quarry_in_box')
                    else if (itemId === 'effect99:steam_engine') give(player, 'effect99:steam_engine_placer')
                    else if (itemId === 'effect99:steam_generator') give(player, 'effect99:steam_generator_placer')
                    else if (itemId === 'effect99:inefficient_steam_engine') give(player, 'effect99:inefficient_steam_engine_placer')
                    else if (itemId === 'effect99:inefficient_steam_generator') give(player, 'effect99:inefficient_steam_generator_placer')
                    else if (itemId === 'effect99:conveyor_belt_north' || itemId === 'effect99:conveyor_belt_south' || itemId === 'effect99:conveyor_belt_west' || itemId === 'effect99:conveyor_belt_east' || itemId === 'effect99:conveyor_belt_north_off' || itemId === 'effect99:conveyor_belt_south_off' || itemId === 'effect99:conveyor_belt_west_off' || itemId === 'effect99:conveyor_belt_east_off') give(player, 'effect99:conveyor_belt')
                    else if (itemId === 'effect99:conveyor_tube_north' || itemId === 'effect99:conveyor_tube_south' || itemId === 'effect99:conveyor_tube_west' || itemId === 'effect99:conveyor_tube_east' || itemId === 'effect99:conveyor_tube_up' || itemId === 'effect99:conveyor_tube_down' || itemId === 'effect99:conveyor_tube_north_off' || itemId === 'effect99:conveyor_tube_south_off' || itemId === 'effect99:conveyor_tube_west_off' || itemId === 'effect99:conveyor_tube_east_off' || itemId === 'effect99:conveyor_tube_up_off' || itemId === 'effect99:conveyor_tube_down_off') give(player, 'effect99:conveyor_tube')
                    else if (itemId === "effect99:antenna" || itemId === "effect99:antenna_signal" || itemId === "effect99:conveyor_tube_station_up" || itemId === "effect99:power_generating_furnace_up") give(player, 'minecraft:air', true)
                }
            } catch (e) { }
        }

        for (const worlds of dimensions) {
            try {
                for (const entity of world.getDimension(worlds).getEntities()) {
                    if (entity.typeId === 'entity:mechanical_arm' || entity.typeId === 'entity:regular_mechanical_arm' || entity.typeId === 'entity:fast_mechanical_arm') {
                        const dimension = world.getDimension(entity.dimension.id)
                        let { x, y, z } = entity.location
                        x = Math.floor(x); y = Math.floor(y); z = Math.floor(z)
                        const block = dimension.getBlock(new BlockLocation(x, y, z)).permutation
                        switch (entity.getComponent('minecraft:variant').value) {
                            case 0:
                                if (dimension.getBlock(new BlockLocation(x, y, z - 1)).hasTag('need_fuel_1') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x, y, z + 1, dimension, x, y, z - 1)
                                else if (dimension.getBlock(new BlockLocation(x, y, z - 2)).hasTag('need_fuel_2') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x, y, z + 1, dimension, x, y, z - 2)
                                break
                            case 1:
                                if (dimension.getBlock(new BlockLocation(x, y, z + 1)).hasTag('need_fuel_1') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x, y, z - 1, dimension, x, y, z + 1)
                                else if (dimension.getBlock(new BlockLocation(x, y, z + 2)).hasTag('need_fuel_2') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x, y, z - 1, dimension, x, y, z + 2)
                                break
                            case 2:
                                if (dimension.getBlock(new BlockLocation(x - 1, y, z)).hasTag('need_fuel_1') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x + 1, y, z, dimension, x - 1, y, z)
                                else if (dimension.getBlock(new BlockLocation(x - 2, y, z)).hasTag('need_fuel_2') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x + 1, y, z, dimension, x - 2, y, z)
                                break
                            case 3:
                                if (dimension.getBlock(new BlockLocation(x + 1, y, z)).hasTag('need_fuel_1') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x - 1, y, z, dimension, x + 1, y, z)
                                else if (dimension.getBlock(new BlockLocation(x + 2, y, z)).hasTag('need_fuel_2') && !block.getProperty('cooldown:arm').value)
                                    fuelProvider(block, x, y, z, entity, x - 1, y, z, dimension, x + 2, y, z)
                                break
                        }
                    }
                }
            } catch (e) { /* console.error(e) */ }
        }
    }
})
function fuelProvider(block, x, y, z, entity, ex, ey, ez, dimension, bx, by, bz) {
    let i = 0
    for (const item of entity.dimension.getEntitiesAtBlockLocation(new BlockLocation(ex, ey, ez))) {
        if (i) break; i++
        const { typeId, amount, data } = item.getComponent('minecraft:item').itemStack
        if (fuelTypeA.includes(typeId) || fuelTypeB.includes(typeId) || fuelTypeC.includes(typeId) || fuelTypeD.includes(typeId) || (typeId.includes('minecraft:') && keywordFuel.some(i => { return typeId.includes(i) }))) {
            const { x: ix, y: iy, z: iz } = item.location
            //world.say(`${typeId}, ${amount}, ${data}`)
            block.getProperty('cooldown:arm').value = 1
            if (fuelTypeA.includes(typeId)) {
                entity.runCommandAsync(`playanimation @s animation.${entity.typeId.slice(entity.typeId.indexOf(":") + 1)}.move`); dimension.spawnEntity('entity:fuel_provider<fuel_1>', new BlockLocation(bx, by, bz))
                dimension.getBlock(new BlockLocation(x, y, z)).setPermutation(block)
                if (amount - 1) {
                    dimension.spawnItem(new ItemStack(ItemTypes.get(typeId), amount - 1, data), new Location(ix, iy, iz))
                    item.kill()
                } else item.kill()
            }
            else if (fuelTypeB.includes(typeId)) {
                entity.runCommandAsync(`playanimation @s animation.${entity.typeId.slice(entity.typeId.indexOf(":") + 1)}.move`); dimension.spawnEntity('entity:fuel_provider<fuel_2>', new BlockLocation(bx, by, bz))
                dimension.getBlock(new BlockLocation(x, y, z)).setPermutation(block)
                if (amount - 1) {
                    dimension.spawnItem(new ItemStack(ItemTypes.get(typeId), amount - 1, data), new Location(ix, iy, iz))
                    item.kill()
                } else item.kill()
            }
            else if (fuelTypeC.includes(typeId)) {
                entity.runCommandAsync(`playanimation @s animation.${entity.typeId.slice(entity.typeId.indexOf(":") + 1)}.move`); dimension.spawnEntity('entity:fuel_provider<fuel_3>', new BlockLocation(bx, by, bz))
                dimension.getBlock(new BlockLocation(x, y, z)).setPermutation(block)
                if (amount - 1) {
                    dimension.spawnItem(new ItemStack(ItemTypes.get(typeId), amount - 1, data), new Location(ix, iy, iz))
                    item.kill()
                } else item.kill()
            }
            else if (fuelTypeD.includes(typeId) || (typeId.includes('minecraft:') && keywordFuel.some(i => { return typeId.includes(i) }))) {
                entity.runCommandAsync(`playanimation @s animation.${entity.typeId.slice(entity.typeId.indexOf(":") + 1)}.move`); dimension.spawnEntity('entity:fuel_provider<fuel_4>', new BlockLocation(bx, by, bz))
                dimension.getBlock(new BlockLocation(x, y, z)).setPermutation(block)
                if (amount - 1) {
                    dimension.spawnItem(new ItemStack(ItemTypes.get(typeId), amount - 1, data), new Location(ix, iy, iz))
                    item.kill()
                } else item.kill()
            }
        }
    }
}

function give(player, item, message = false) {
    player.runCommandAsync(`replaceitem entity @s slot.weapon.mainhand 0 ${item}`)
    if (message) player.onScreenDisplay.setActionBar(`You do not have permission\n to have this item`)
}

world.events.beforeChat.subscribe(chat => {
    if (chat.message === '!admin') {
        chat.cancel = true
        admin = true
        world.say(`Admin ${chat.sender.name}`)
    } else if (chat.message === '!admin!') {
        chat.cancel = true
        admin = false
        world.say(`User ${chat.sender.name}`)
    }
})

const fuelTypeA = [
    'minecraft:coal_block',
    'minecraft:blaze_rod',
    'minecraft:lava_bucket'
]

const fuelTypeB = [
    'minecraft:coal',
    'minecraft:charcoal',
    'minecraft:dried_kelp_block',
    'minecraft:blaze_powder'
]

const fuelTypeC = [
    'minecraft:planks',
    'minecraft:log',
    'minecraft:log2',
    'minecraft:planks',
    'minecraft:wood',
    'minecraft:stripped_acacia_log',
    'minecraft:stripped_birch_log',
    'minecraft:stripped_dark_oak_log',
    'minecraft:stripped_jungle_log',
    'minecraft:stripped_oak_log',
    'minecraft:stripped_spruce_log',
    'minecraft:mangrove_wood',
    'minecraft:wooden_door',
    'minecraft:wool',
    'minecraft:lectern',
    'minecraft:chest',
    'minecraft:trapped_chest',
    'minecraft:barrel',
    'minecraft:composter',
    'minecraft:crafting_table',
    'minecraft:bookshelf',
    'minecraft:noteblock'
]

const fuelTypeD = [
    'minecraft:stick',
    'minecraft:ladder',
    'minecraft:deadbush',
    'minecraft:sapling'
]

const keywordFuel = [
    'jungle',
    'acacia',
    'birch',
    'dark_oak',
    'spruce',
    'mangrove',
    'oak',
    'wooden',
    'leaves',
    'azalea'
]