import { Block } from "@minecraft/server"

/**
 * List of Minecraft Blocks and their custom tags
 * ```
 * keyword - Literal Block ids
 * #keyword - Blocks with tag `keyword`
 * .keyword - Block ids ending with `keyword`
 * /keyword - Block ids starting with `keyword` 
 * ~keyword - Block ids containing `keyword`
 * ```
 */
export class CustomBlockTags {
    /**
     * Blocks that cannot be attached with head
     */
    static #no_head = [ 
        /**
         * VANILLA BLOCKS
         */
        "minecraft:ladder",
        ".carpet",
        "minecraft:sea_pickle",
        ".sapling",
        "minecraft:fern",
        "minecraft:large_fern",
        "minecraft:short_grass",
        "minecraft:tall_grass",
        "minecraft:nether_sprouts",
        "minecraft:twisting_vines",
        "minecraft:sea_grass",
        "minecraft:kelp",
        "minecraft:weeping_vines",
        "minecraft:bamboo_sampling",
        "minecraft:hanging_roots",
        "minecraft:big_dripleaf",
        "minecraft:small_dripleaf_block",
        "minecraft:spore_blossom",
        "minecraft:glow_lichen",
        "minecraft:red_mushroom",
        "minecraft:brown_mushroom",
        "minecraft:frog_spawn",
        "minecraft:nether_wart",
        "minecraft:sculk_vein",
        ".candle",
        "minecraft:frame",
        "minecraft:glow_frame",
        "minecraft:skull",
        "minecraft:flower_pot",
        "minecraft:torchflower",
        "minecraft:pink_petals",
        "minecraft:peony",
        "minecraft:rose_bush",
        "minecraft:lilac",
        "minecraft:sunflower",
        "minecraft:azure_bluet",
        "minecraft:red_tulip",
        "minecraft:oxeye_daisy",
        "minecraft:cornflower",
        "minecraft:lily_of_the_valley",
        "minecraft:allium",
        "minecraft:pitcher_plant",
        "minecraft:blue_orchid",
        "minecraft:poppy",
        "minecraft:yellow_flower",
        "minecraft:pink_tulip",
        "minecraft:white_tulip",
        "minecraft:orange_tulip",
        "minecraft:wither_rose",
        "#rail",
        "minecraft:tripwire_hook",
        "minecraft:unpowered_comparator",
        "minecraft:unpowered_repeater",
        "minecraft:powered_repeater",
        "minecraft:powered_comparator",
        "#crops",
        "minecraft:warped_roots",
        "minecraft:crimson_roots",
        "minecraft:vine",
        "minecraft:fire",
        "minecraft:soul_fire",
        "#water",
        "minecraft:air",

        /**
         * CUSTOM BLOCKS
         */
        "#piki_beyondsurvival:skull"
    ]
    static #no_head_on_side = [
        "minecraft:scaffolding",
        "minecraft:end_rod"
    ]
    static #place_head_as_up = [
        "minecraft:snow_layer"
    ]
    /**
     * Blocks that requires sneaking to place block
     */
    static #sneak_required = [ 
        "minecraft:fence_gate",
        ".door",
        "minecraft:bed",
        "minecraft:vault",
        "minecraft:crafting_table",
        "minecraft:cartography_table",
        "minecraft:smithing_table",
        "minecraft:anvil",
        "minecraft:blast_furnace",
        "minecraft:smoker",
        "minecraft:brewing_stand",
        "minecraft:furnace",
        "minecraft:grind_stone",
        "minecraft:enchanting_table",
        "minecraft:lectern",
        "minecraft:cauldron",
        "minecraft:composter",
        "minecraft:chest",
        "minecraft:trapped_chest",
        "minecraft:ender_chest",
        "minecraft:barrel",
        ".shulker_box",
        "minecraft:jukebox",
        "#text_sign",
        "minecraft:stonecutter_block",
        ".button",
        "minecraft:lever",
        "minecraft:redstone_torch",
        "minecraft:redstone_wire",
        "minecraft:daylight_detector",
        "minecraft:hopper",
        "minecraft:dropper",
        "minecraft:dispenser",
        "minecraft:crafter",
        "minecraft:decorated_pot",
        ".command_block",
        "minecraft:bell"
    ]
    static #sneak_required_on_side = [
        "minecraft:bell",
        "minecraft:noteblock",
        "minecraft:chiseled_bookshelf"
    ]
    /**
     * Blocks that will be replaced when placing a block on
     */
    static #replace_target_block = [
        "minecraft:fern",
        "minecraft:large_fern",
        "minecraft:short_grass",
        "minecraft:tall_grass",
        "minecraft:nether_sprouts",
        "minecraft:warped_roots",
        "minecraft:crimson_roots",
        "minecraft:vine",
        "minecraft:fire",
        "minecraft:soul_fire",
        "#water",
        "minecraft:air",
        "minecraft:snow_layer",
        "minecraft:lava",
        "minecraft:flowing_lava"
    ]
    static #replace_self_block = [
        "minecraft:snow_layer"
    ]
    static #is_vanilla = [
        "/minecraft:"
    ]
    static #is_custom = [
        "/piki_beyondsurvival:"
    ]
    static #is_brick = [
        "._bricks"
    ]
    static #is_pillar = [
        "._pillar"
    ]
    static #drop_custom_bark = [
        "#wood",
        "#log",

        "#piki_beyondsurvival:custom_logs",
        "#piki_beyondsurvival:custom_woods"
    ]
    static #venomite_shovel_breakable = [
        "#dirt",
        "#sand",
        "#snow",
        "|#minecraft:soul_fire_base_blocks",
        "#gravel",
        "._concrete_powder",
        "minecraft:packed_mud"
    ]
    static #venomite_pickaxe_breakable = [
        "#stone_bricks",
        "#base_stone_overworld",
        "#stone_ore_replaceables",
        "#stone",
        "#base_stone_nether",
        "._ore",
        "minecraft:deepslate",
        "minecraft:netherrack",
        "minecraft:blackstone",
        "minecraft:magma",
        "minecraft:basalt",
        "minecraft:end_stone",
        "minecraft:calcite",
        "!~glazed",
        "._terracotta",
        "minecraft:amethyst_block",
        "minecraft:tuff"

    ]
    static #venomite_axe_breakable = [
        "#log",
        "#wood",
        "._leaves",
        "._leaves_flowered",    
        "|#minecraft:logs",
        ".bamboo_block",
        "._hyphae",
        "#pumpkin",
        "minecraft:melon_block",

        "#piki_beyondsurvival:custom_logs",
        "#piki_beyondsurvival:custom_woods"
    ]
    static #venomite_sword_breakable = [
        "minecraft:web"
    ]
    static #venomite_hoe_breakable = [
        "#minecraft:crop"
    ]
    static #will_not_cost_durability = [
        "minecraft:powered_comparator",
        "minecraft:unpowered_comparator",
        "minecraft:unpowered_repeater",
        "minecraft:powered_repeater",
        "minecraft:redstone_torch",
        "minecraft:unlit_redstone_torch",
        "minecraft:redstone_wire",
        "minecraft:trip_wire",
        "minecraft:tripwire_hook",
        "minecraft:azalea",
        "minecraft:deadbush",
        "minecraft:dead_tube_coral",
        "minecraft:dead_brain_coral",
        "minecraft:dead_bubble_coral",
        "minecraft:dead_fire_coral",
        "minecraft:dead_horn_coral",
        "minecraft:coral_fan_dead",
        // "minecraft:dead_tube_coral_fan",
        // "minecraft:dead_brain_coral_fan",
        // "minecraft:dead_bubble_coral_fan",
        // "minecraft:dead_fire_coral_fan",
        // "minecraft:dead_horn_coral_fan",
        "minecraft:coral_fan_hang",
        "minecraft:coral_fan_hang2",
        "minecraft:coral_fan_hang3",
        "minecraft:tallgrass",
        "minecraft:hanging_roots",
        "minecraft:kelp",
        "minecraft:waterlily",
        "minecraft:mangrove_propagule",
        "minecraft:crimson_fungus",
        "minecraft:warped_fungus",

        "#saplings",
        "#crops",
        "#coral",
        "#coral_plants",
        "#underwater_bonemeals",
        "#wall_corals",

        "#piki_beyondsurvival:instant_break",
    ]
    
    static #is_stripped = [
        "~stripped"
    ]

    static isStripped(block) {
        const list = CustomBlockTags.#is_stripped
        return CustomBlockTags.matches(list, block)
    }

    static willNotCostDurability(block) {
        const list = CustomBlockTags.#will_not_cost_durability
        return CustomBlockTags.matches(list, block)
    }

    static isVenomiteShovelBreakable(block) {
        const list = CustomBlockTags.#venomite_shovel_breakable
        return CustomBlockTags.matches(list, block)
    }
    static isVenomiteSwordBreakable(block) {
        const list = CustomBlockTags.#venomite_sword_breakable
        return CustomBlockTags.matches(list, block)
    }
    static isVenomiteHoeBreakable(block) {
        const list = CustomBlockTags.#venomite_hoe_breakable
        return CustomBlockTags.matches(list, block)
    }
    static isVenomiteAxeBreakable(block) {
        const list = CustomBlockTags.#venomite_axe_breakable
        return CustomBlockTags.matches(list, block)
    }
    static isVenomitePickaxeBreakable(block) {
        const list = CustomBlockTags.#venomite_pickaxe_breakable
        return CustomBlockTags.matches(list, block)
    }
    static replaceAsSelf(block) {
        const list = CustomBlockTags.#replace_self_block
        return CustomBlockTags.matches(list, block)
    }
    static replaceAsTarget(block) {
        const list = CustomBlockTags.#replace_target_block
        return CustomBlockTags.matches(list, block)
    }
    static isSneakRequiredOnSide(block) {
        const list = CustomBlockTags.#sneak_required_on_side
        return CustomBlockTags.matches(list, block)
    }
    static isSneakRequired(block) {
        const list = CustomBlockTags.#sneak_required
        return CustomBlockTags.matches(list, block)
    }
    static placeHeadAsUp(block) {
        const list = CustomBlockTags.#place_head_as_up
        return CustomBlockTags.matches(list, block)
    }
    static notHeadAttachableOnSide(block) {
        const list = CustomBlockTags.#no_head_on_side
        return CustomBlockTags.matches(list, block)
    }
    static notHeadAttachable(block) {
        const list = CustomBlockTags.#no_head
        return CustomBlockTags.matches(list, block)
    }
    static dropsCustomBark(block) {
        const list = CustomBlockTags.#drop_custom_bark
        return CustomBlockTags.matches(list, block)
    }
    static isVanilla(block) {
        const list = CustomBlockTags.#is_vanilla
        return CustomBlockTags.matches(list, block)
    }
    static isCustom(block) {
        const list = CustomBlockTags.#is_custom
        return CustomBlockTags.matches(list, block)
    } 
    static isBrick(block) {
        const list = CustomBlockTags.#is_brick
        return CustomBlockTags.matches(list, block)
    } 
    static isPillar(block) {
        const list = CustomBlockTags.#is_pillar
        return CustomBlockTags.matches(list, block)
    } 

    /**
     * Check if block is listed in the array using its information
     * @param {string[]} array 
     * @param {Block} block 
     */
    static matches(array, block) {
        for (const element of array) {
            if (element == block.typeId) return true
            if (element.includes("!")) {
                const itemElement = element.replace("!", "")
                if (itemElement == block.typeId) return false
                if (itemElement.includes("#") && block.hasTag(itemElement.replace("#", ""))) return false
                if (itemElement.includes(".") && block.typeId.endsWith(itemElement.replace(".", ""))) return false
                if (itemElement.includes("/") && block.typeId.startsWith(itemElement.replace("/", ""))) return false
                if (itemElement.includes("~") && block.typeId.includes(itemElement.replace("~", ""))) return false
            }
            if (element.includes("#") && block.hasTag(element.replace("#", ""))) return true
            if (element.includes(".") && block.typeId.endsWith(element.replace(".", ""))) return true
            if (element.includes("/") && block.typeId.startsWith(element.replace("/", ""))) return true
            if (element.includes("~") && block.typeId.includes(element.replace("~", ""))) return true
            if (element.includes("|")) {
                const itemElement = element.replace("|", "")
                const itemStack = block.getItemStack()
                if (!itemStack) continue
                if (itemElement == itemStack.typeId) return true
                if (itemElement.includes("#") && itemStack.hasTag(itemElement.replace("#", ""))) return true
                if (itemElement.includes(".") && itemStack.typeId.endsWith(itemElement.replace(".", ""))) return true
                if (itemElement.includes("/") && itemStack.typeId.startsWith(itemElement.replace("/", ""))) return true
                if (itemElement.includes("~") && itemStack.typeId.includes(itemElement.replace("~", ""))) return true
            }

        }
        return false
    }
}
