import { EntityInventoryComponent } from "@minecraft/server"
import { hasTag } from "../../functions";

const PrefixLores = {
    "netherite": "§r§d Fire Resistance"
};

const SimpleLores = [
    'minecraft:is_sword|"§r§d Sword"',
    'minecraft:is_axe|"§r§d Axe"',
    'minecraft:is_hoe|"§r§d Hoe"',
    'minecraft:is_shovel|"§r§d Shovel"',
    'minecraft:is_pickaxe|"§r§d Pickaxe"',
    'true:is_spear|"§r§d Spear"',
    'true:is_blunt|"§r§d Blunt"',
    'weight:0|"§r§d Light"',
    'weight:1|"§r§d Heavy"',
    'weight:2|"§r§d Very Heavy"',
    'weight:3|"§r§dUnsustainable"',
    'fracture|"§r§d Broken Bones"'
]

const vanillaTags = [
    "minecraft:is_sword",
    "minecraft:is_axe",
    "minecraft:is_hoe",
    "minecrafT:is_pickaxe",
    "minecraft:is_shovel"
]

const regexpLores = {
    "§r§d Sweeping": /[A-z]+_sweep:[0-9]+/,
    "§r§d Bleeding": /sharp:[0-9]+:[0-9]+:[0-9]+/,
    "§r§d Stabbing": /stabbing:[0-9]+/
};

class LoreManager {
    constructor() {
        this.regexp = /"(.*?)"/g;
        this.tag_regexp = /^([^|"\s]+)/;
    }

    applyLoreToInventory(player) {
        const playerInventoryContainer = player.getComponent(EntityInventoryComponent.componentId)?.container;

        for (let i = 0; i < playerInventoryContainer.size; i++) {
            const item = playerInventoryContainer.getItem(i);

            if (!item) continue;
            const lores = [...this._bySimpleTag(item), ...this._byRegexp(item), ...this._byPrefix(item)];

            item.setLore(lores.flat());
            playerInventoryContainer.setItem(i, item)
        }
    }

    _bySimpleTag(itemStack) {
        const itemTags = this._getItemTags(itemStack)
        const itemLoresRaw = SimpleLores.filter(lore => hasTag(itemStack, lore.match(this.tag_regexp)[0]));
        const itemLores = this._parseRawLores(itemLoresRaw);

        if (this._isVanillaWeapon(itemTags) && itemStack.typeId.startsWith("minecraft:")) itemLores.push("§r§d Medium"); 
        if (itemStack.typeId.startsWith("true:") && !this._hasWeightTag(itemTags)) itemLores.push("§r§d Medium");
        return itemLores;
    }

    _getItemTags(ItemStack) {
        return SimpleLores
            .map(lore => lore.match(this.tag_regexp)[0])
            .filter(tag => hasTag(ItemStack, tag));
    }

    _hasWeightTag(ItemTags) {
        return ItemTags.some(tag => tag.includes("weight:"));
    }

    _isVanillaWeapon(itemTags) {
        return vanillaTags.some(tag => itemTags.includes(tag));
    }

    _parseRawLores(lores) {
        return lores
            .map(itemLoreRaw => itemLoreRaw.match(this.regexp)
                .map(match => match.replace(/"/g, '')))
            .flat();
    }

    _byRegexp(ItemStack) {
        const lores = [];

        for (const [regexpLore, regexp] of Object.entries(regexpLores)) {
            if (hasTag(ItemStack, null, regexp)) lores.push(regexpLore);
        }
        return lores;
    }

    _byPrefix(ItemStack) {
        const lores = [];

        for (const prefix of Object.keys(PrefixLores)) {
            if (ItemStack.typeId.includes(prefix)) lores.push(PrefixLores[prefix]);
        }
        return lores;
    }

    _itemHasTag(itemStack, tag) {
        return itemStack.getTags()?.find(tag);
    }
}

export default new LoreManager();