import { world, system, ItemStack, BlockPermutation, MolangVariableMap } from "@minecraft/server";
import { fence_Manager } from './fence_Manager'

world.beforeEvents.worldInitialize.subscribe(initEvent => {
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:mug_holder', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            if (item?.typeId == "bumble:mug" && block.permutation.getState('bumble:mugs') < 4) {
                block.setPermutation(block.permutation.withState('bumble:mugs', block.permutation.getState('bumble:mugs') + 1))
                block.dimension.playSound('step.decorated_pot', block.center())
                decrementstack(item, player)
            }
            else if (block.permutation.getState('bumble:mugs') > 0) {
                block.dimension.spawnItem(new ItemStack("bumble:mug"), { x: block.location.x + 0.5, y: block.location.y + 0.3, z: block.location.z + 0.5 })
                block.setPermutation(block.permutation.withState('bumble:mugs', block.permutation.getState('bumble:mugs') - 1))
                block.dimension.playSound('mob.sniffer.plop', block.center())
            }
        },
    });

    initEvent.itemComponentRegistry.registerCustomComponent('bumble:random_seed_bag', {
        onUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.typeId == 'bumble:random_seed_bag') {
                player.dimension.playSound('mob.sniffer.plop', { x: player.location.x, y: player.location.y, z: player.location.z })
                player.dimension.runCommandAsync('loot spawn ' + JSON.stringify(player.location.x) + ' ' + JSON.stringify(player.location.y) + ' ' + JSON.stringify(player.location.z) + ' loot ' + 'random_seed_loot')
                decrementstack(item, player, item.typeId)
            }
        },
    });

    //Item Effects
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:speed', {
        onCompleteUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.typeId == 'bumble:coffee_brew') {
                add_effect(player, 'speed', 2400, 1)
                add_effect(player, 'haste', 2400, 1)
                add_effect(player, 'jump_boost', 2400, 0)
                add_effect(player, 'hunger', 100, 0)
            }
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:high', {
        onCompleteUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.typeId == 'bumble:smokeleaf_joint') {
                add_effect(player, 'health_boost', 2400, 1)
                add_effect(player, 'slow_falling', 1200, 1)
                add_effect(player, 'jump_boost', 800, 0)
                add_effect(player, 'hunger', 600, 4)
            }
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:mead_effects', {
        onCompleteUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.typeId == 'bumble:mead_foul' || item.typeId == 'bumble:mead_rotten') {
                add_effect(player, 'nausea', 300, 1)
            }
            else {
                add_effect(player, 'nausea', 200, 0)
            }
            if (item.typeId == 'bumble:mead_charming') {
                add_effect(player, 'invisibility', 200, 0)
                player.runCommandAsync('camerashake add @p 0.55 6 positional')
            }
            if (item.typeId == 'bumble:mead_foul' || item.typeId == 'bumble:mead_rotten') {
                add_effect(player, 'weakness', 400, 0)
                add_effect(player, 'slowness', 500, 0)
            }
            if (item.typeId == 'bumble:mead_jolly') {
                add_effect(player, 'water_breathing', 200, 0)
                add_effect(player, 'night_vision', 200, 0)
            }
            if (item.typeId == 'bumble:mead_sweet') {
                add_effect(player, 'speed', 200, 0)
                add_effect(player, 'haste', 300, 0)
                player.runCommandAsync('camerashake add @p 0.45 8 rotational')
            }
            if (item.typeId == 'bumble:mead_warm') {
                add_effect(player, 'fire_resistance', 200, 0)
                add_effect(player, 'jump_boost', 300, 1)
            }
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:tea_effects', {
        onCompleteUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.typeId == 'bumble:tea_chamomile') {
                add_effect(player, 'absorption', 500, 0)
                add_effect(player, 'regeneration', 200, 0)
            }
            if (item.typeId == 'bumble:tea_lavender') {
                add_effect(player, 'absorption', 700, 0)
                add_effect(player, 'conduit_power', 600, 0)
            }
            if (item.typeId == 'bumble:tea_mint') {
                add_effect(player, 'absorption', 500, 0)
                add_effect(player, 'fire_resistance', 200, 0)
            }
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:wine_effects', {
        onCompleteUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.typeId != 'bumble:wine_witherosa' || item.typeId != 'bumble:wine_sweet') {
                add_effect(player, 'nausea', 200, 0)
            }
            if (item.typeId == 'bumble:wine_cherry') {
                add_effect(player, 'instant_health', 200, 0)
                add_effect(player, 'slow_falling', 200, 1)
            }
            if (item.typeId == 'bumble:wine_strawberry') {
                add_effect(player, 'regeneration', 100, 0)
            }
            if (item.typeId == 'bumble:wine_sweet') {
                add_effect(player, 'nausea', 200, 4)
                add_effect(player, 'levitation', 200, 1)
                add_effect(player, 'slow_falling', 300, 0)
                add_effect(player, 'blindness', 200, 0)
                player.runCommandAsync('camerashake add @p 0.55 10 rotational')
            }
            if (item.typeId == 'bumble:wine_witherosa') {
                add_effect(player, 'nausea', 999999, 0)
                add_effect(player, 'darkness', 999999, 4)
                add_effect(player, 'wither', 999999, 1)
            }
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:ale_effects', {
        onCompleteUse: e => {
            const item = e.itemStack
            const player = e.source
            if (item.hasTag('bumble:ale_bitter')) {
                add_effect(player, 'nausea', 200, 0)
                add_effect(player, 'slowness', 200, 0)
                add_effect(player, 'regeneration', 200, 0)
                player.runCommandAsync('camerashake add @p 0.25 6 rotational')
            }
            if (item.hasTag('bumble:ale_bold')) {
                add_effect(player, 'nausea', 200, 0)
                add_effect(player, 'strength', 200, 0)
                add_effect(player, 'resistance', 300, 0)
            }
            if (item.hasTag('bumble:ale_dry')) {
                add_effect(player, 'nausea', 200, 0)
                add_effect(player, 'haste', 300, 0)
                add_effect(player, 'fire_resistance', 200, 0)
            }
            if (item.hasTag('bumble:ale_euphoric')) {
                add_effect(player, 'nausea', 200, 0)
                add_effect(player, 'slow_falling', 300, 0)
                add_effect(player, 'levitation', 200, 0)
            }
            if (item.hasTag('bumble:ale_foul')) {
                add_effect(player, 'nausea', 300, 0)
                add_effect(player, 'weakness', 400, 0)
                add_effect(player, 'slowness', 500, 0)
            }
            if (item.hasTag('bumble:ale_potent')) {
                add_effect(player, 'nausea', 240, 0)
                add_effect(player, 'blindness', 200, 0)
                player.runCommandAsync('camerashake add @p 0.45 8 rotational')
            }
            if (item.typeId == 'bumble:ale') {
                add_effect(player, 'nausea', 200, 0)
            }
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:remove_weakness', {
        onCompleteUse: e => {
            const player = e.source
            player.removeEffect('weakness')
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:remove_poison', {
        onCompleteUse: e => {
            const player = e.source
            player.removeEffect('poison')
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:water_breathing', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'water_breathing', 600, 0)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:chili_speed', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'speed', 100, 1)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:haste', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'haste', 100, 0)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:dragon_fruit_wither', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'wither', 60, 0)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:jam_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'health_boost', 80, 0)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:sandwich_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'health_boost', 200, 0)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:maple_syrup_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'fire_resistance', 600, 1)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:aloe_leaf_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'fire_resistance', 400, 1)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:lemon_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'nausea', 80, 2)
            add_effect(player, 'night_vision', 80, 0)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:flapjack_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'instant_health', 120, 2)
            add_effect(player, 'resistance', 600, 1)
            add_effect(player, 'slow_falling', 600, 1)
            add_effect(player, 'fire_resistance', 600, 2)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:shrooms', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'jump_boost', 800, 7)
            add_effect(player, 'nausea', 300, 3)
            add_effect(player, 'slow_falling', 1200, 3)
        },
    });
    initEvent.itemComponentRegistry.registerCustomComponent('bumble:cattail_reed_effects', {
        onCompleteUse: e => {
            const player = e.source
            add_effect(player, 'hunger', 80, 3)
            add_effect(player, 'nausea', 80, 3)
            player.runCommandAsync('particle minecraft:snowflake_particle ~ ~ ~')
            player.runCommandAsync('particle minecraft:snowflake_particle ~ ~ ~')
            player.runCommandAsync('particle minecraft:snowflake_particle ~ ~ ~')
            player.runCommandAsync('particle minecraft:snowflake_particle ~ ~ ~')
        },
    });
    //General Components
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:random_direction', {
        onPlace: e => {
            let num = Math.round(Math.random() * 4)
            const block = e.block
            if (num == 4) {
                block.setPermutation(block.permutation.withState('minecraft:cardinal_direction', "north"))
            }
            if (num == 3) {
                block.setPermutation(block.permutation.withState('minecraft:cardinal_direction', "south"))
            }
            if (num == 2) {
                block.setPermutation(block.permutation.withState('minecraft:cardinal_direction', "east"))
            }
            if (num <= 1) {
                block.setPermutation(block.permutation.withState('minecraft:cardinal_direction', "west"))
            }
        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:reset_top', {
        onPlayerDestroy: e => {
            const block = e.block
            block.above(1).setPermutation(BlockPermutation.resolve('minecraft:air'))
        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:reset_bottom', {
        onPlayerDestroy: e => {
            const block = e.block
            block.below(1).setPermutation(BlockPermutation.resolve('minecraft:air'))
        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:fence_place', {
        onPlace: e => {
            const block = e.block
            block.setPermutation(block.permutation.withState('bumble:on_placed', true))
        },
    });

    //Buckets
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:take_bucket', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            block.dimension.playSound('mob.sniffer.drop_seed', block.center())
            player.runCommandAsync('loot spawn ' + JSON.stringify(block.location.x) + ' ' + JSON.stringify(block.location.y + 1) + ' ' + JSON.stringify(block.location.z) + ' loot "sap/empty_bucket"')
            block.setPermutation(block.permutation.withState('bumble:has_bucket', false))
            block.setPermutation(block.permutation.withState('bumble:sap_level', 0))
        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:sap_bucket', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            block.dimension.playSound('land.honey_block', block.center())
            player.runCommandAsync('loot spawn ' + JSON.stringify(block.location.x) + ' ' + JSON.stringify(block.location.y + 1) + ' ' + JSON.stringify(block.location.z) + ' loot "sap/sap_bucket"')
            block.setPermutation(block.permutation.withState('bumble:has_bucket', false))
            block.setPermutation(block.permutation.withState('bumble:sap_level', 0))
        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:sap_tick', {
        onRandomTick: e => {
            const block = e.block
            let num = Math.round(Math.random() * 50)
            if (num <= 1) {
                if (block.permutation.getState('bumble:sap_level') < 2) {
                    block.setPermutation(block.permutation.withState('bumble:sap_level', block.permutation.getState('bumble:sap_level') + 1))
                }
            }

        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:persistent', {
        onPlace: e => {
            const block = e.block
            block.setPermutation(block.permutation.withState('bumble:decay', 1))
            block.setPermutation(block.permutation.withState('bumble:can_despawn', false))
        },
    });

    //Slab Related
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:grass_to_dirt', {
        onTick: e => {
            const block = e.block
            if (block.below(1).typeId == 'minecraft:grass') {
                block.below(1).setPermutation(BlockPermutation.resolve("minecraft:dirt"))
            }
        },
    });

    initEvent.blockComponentRegistry.registerCustomComponent('bumble:double_slab', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            double_slab(block, item, player, "cherry")
            double_slab(block, item, player, "lemon")
            double_slab(block, item, player, "maple")
            double_slab(block, item, player, "orange")
            double_slab(block, item, player, "peach")
            double_slab(block, item, player, "pear")

        },
    });
    //Doors
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:open', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            if (block.hasTag('bumble:trapdoor')) {
                if (block.permutation.getState('bumble:is_open') == false) {
                    block.setPermutation(block.permutation.withState('bumble:is_open', true))
                    block.dimension.playSound('open.wooden_trapdoor', block.center())
                }
                else if (block.permutation.getState('bumble:is_open') == true) {
                    block.setPermutation(block.permutation.withState('bumble:is_open', false))
                    block.dimension.playSound('close.wooden_trapdoor', block.center())
                }
            }
            if (block.hasTag('bumble:fence_gate')) {
                if (block.permutation.getState('bumble:is_open') == false) {
                    block.setPermutation(block.permutation.withState('bumble:is_open', true))
                    block.dimension.playSound('open.fence_gate', block.center())
                }
                else if (block.permutation.getState('bumble:is_open') == true) {
                    block.setPermutation(block.permutation.withState('bumble:is_open', false))
                    block.dimension.playSound('close.fence_gate', block.center())
                }
            }
        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:door_open', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            if (block.hasTag('bumble:door')) {
                if (block.permutation.getState('bumble:is_open') == false) {
                    door_open_close(block, true)
                    if (!(block.hasTag("bumble:door_top"))) {
                        door_open_close(block.above(1), true)
                    }
                    if (block.hasTag("bumble:door_top")) {
                        door_open_close(block.below(1), true)
                    }
                }
            }

        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:door_close', {
        onPlayerInteract: e => {
            const block = e.block
            const player = e.player
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            if (block.hasTag('bumble:door')) {
                if (block.permutation.getState('bumble:is_open') == true) {
                    door_open_close(block, false)
                    if (!(block.hasTag("bumble:door_top"))) {
                        door_open_close(block.above(1), false)
                    }
                    if (block.hasTag("bumble:door_top")) {
                        door_open_close(block.below(1), false)
                    }
                }
            }

        },
    });
    initEvent.blockComponentRegistry.registerCustomComponent('bumble:door_place', {
        onPlace: e => {
            const block = e.block

            switch (block.typeId) {
                case "bumble:cherry_door_bottom":
                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:cherry_door_top"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:cherry_door_bottom_flipped":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:cherry_door_top_flipped"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:lemon_door_bottom":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:lemon_door_top"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:lemon_door_bottom_flipped":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:lemon_door_top_flipped"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:maple_door_bottom":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:maple_door_top"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:maple_door_bottom_flipped":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:maple_door_top_flipped"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:orange_door_bottom":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:orange_door_top"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:orange_door_bottom_flipped":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:orange_door_top_flipped"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:peach_door_bottom":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:peach_door_top"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:peach_door_bottom_flipped":

                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:peach_door_top_flipped"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:pear_door_bottom":
                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:pear_door_top"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;

                case "bumble:pear_door_bottom_flipped":
                    block.above(1).setPermutation(BlockPermutation.resolve("bumble:pear_door_top_flipped"))
                    block.above(1).setPermutation(block.above(1).permutation.withState('minecraft:cardinal_direction', block.permutation.getState('minecraft:cardinal_direction')))
                    break;
            }
        },
    });
});

//time in ticks! Amplifier starts at 0 for tier 1
export function add_effect(player, effect_name, time, amplifier) {
    player.addEffect(effect_name, time, { amplifier: amplifier })
}

//Decrement stack
export function decrementstack(item, user) {
    if (!(item?.typeId == undefined)) {
        if (item.amount > 1) {
            item.amount--;
            user.getComponent('equippable').setEquipment('Mainhand', item)
        }
        else if (item.amount === 1) {
            user.getComponent('equippable').setEquipment('Mainhand', undefined)
        }
    }
}

function double_slab(block, item, player, type) {
    let req = "bumble:" + type + "_slab"
    if (block.typeId == req && item?.typeId == req) {
        block.dimension.playSound('use.wood', block.center())
        decrementstack(item, player)
        block.setPermutation(BlockPermutation.resolve("bumble:" + type + "_double_slab"))
    }
}

export function adjustItemDamage(playerEquip, itemStack, damageToAdd, slot) {
    const durabilityComp = itemStack.getComponent('minecraft:durability');
    if (!durabilityComp) return;
    if (durabilityComp.damage === durabilityComp.maxDurability && playerEquip) {
        playerEquip.setItem(slot, undefined);
    } else {
        durabilityComp.damage = Math.min(durabilityComp.damage + damageToAdd, durabilityComp.maxDurability);
        if (durabilityComp.damage === durabilityComp.maxDurability) {
            playerEquip.setItem(slot, undefined);
        } else {
            playerEquip.setItem(slot, itemStack);
        }
    }
}


function door_open_close(block, istrue) {
    block.setPermutation(block.permutation.withState('bumble:is_open', istrue))
    if (!(block.hasTag('bumble:door_top')) && istrue == true) {
        block.dimension.playSound('open.wooden_door', block.center())
    }
    if (!(block.hasTag('bumble:door_top')) && istrue == false) {
        block.dimension.playSound('close.wooden_door', block.center())
    }

}
world.afterEvents.playerBreakBlock.subscribe((data) => {
    fence_Manager.updateFencesAround(data.block)
})


world.afterEvents.playerPlaceBlock.subscribe((data) => {
    fence_Manager.updateFencesAround(data.block)
})
