import { world, system, ItemStack, Player, EntityInventoryComponent } from "@minecraft/server";
import { ITEM_LORES, SPECIAL_ITEM_LORES, DEFAULT_ITEM_LORE, DEFAULT_ITEM_LORE_LEN } from "../data/lore.js";

// PLAYER PROTOTYPE
Player.prototype.sneakingState = 0;




system.runInterval(() => {

    world.getAllPlayers().forEach((player) => {
        updateSneakingState(player);

        if (player.sneakingState === 3) {

            if (player.isJumping && player.getDynamicProperty("mythicus_tw:addonSettings.hasMInventoryHotkey")) {
                triggerMultiInventory(player);
            }

            let block = undefined;
            try {
                block = player.dimension.getBlock(player.location).below();
            } finally {
                if (block) toggleBlockOutline(block);
            }
        }
    });

}, 5);

system.runInterval(() => {

    for (const player of world.getPlayers()) {
        try {
            updatePlayerInventory(player);
        } catch {
            continue;
        }
    }

}, 20);

function updatePlayerInventory(player) {

    // get player container
    const container = player.getComponent(EntityInventoryComponent.componentId)?.container;
    if (container?.isValid() !== true) return;

    // player-specific properties
    const advancedLore = player.getDynamicProperty("mythicus_tw:addonSettings.advancedItemDescs") ?? true;

    // iterate through inventory
    for (let i = 0; i < container.size; i++) {

        // get item
        const item = container.getItem(i);
        if (!item || !item.typeId.startsWith("mythicus_tw")) continue;

        // remove system items
        const itemTypeId = item.typeId;
        if (itemTypeId.startsWith("mythicus_tw:sys.")) {
            container.setItem(i, undefined);
            continue;
        }

        // update item lore
        const specialLore = SPECIAL_ITEM_LORES[itemTypeId];
        if (advancedLore) {
            if (item.getLore().length > (specialLore ? DEFAULT_ITEM_LORE_LEN + specialLore.length : DEFAULT_ITEM_LORE_LEN)) continue;
            const lore = ITEM_LORES[itemTypeId];
            if (lore) {
                if (specialLore) {
                    const totalLore = item.getLore().length === 0 ? [...specialLore, ...lore] : [...item.getLore().slice(1, specialLore.length + 1), ...lore];
                    item.setLore(["", ...totalLore, ...DEFAULT_ITEM_LORE]);
                } else {
                    item.setLore(["", ...lore, ...DEFAULT_ITEM_LORE]);
                }
                container.setItem(i, item);
            }
        } else {
            if (item.getLore().length !== (specialLore ? DEFAULT_ITEM_LORE_LEN + specialLore.length : DEFAULT_ITEM_LORE_LEN)) {
                if (specialLore) {
                    const totalLore = item.getLore().length === 0 ? [...specialLore, ...DEFAULT_ITEM_LORE] : [...item.getLore().slice(1, specialLore.length + 1), ...DEFAULT_ITEM_LORE];
                    item.setLore(["", ...totalLore]);
                } else {
                    item.setLore(["", ...DEFAULT_ITEM_LORE]);
                }
                container.setItem(i, item);
            }
        }
        

    }

}


function updateSneakingState(player) {

    // get current state data
    const { isSneaking, sneakingState } = player;

    // return if state is unchanged
    if ((isSneaking && sneakingState === 2) || (!isSneaking && sneakingState === 0)) return;

    // update state
    if (isSneaking && sneakingState < 2) {
        player.sneakingState = 3;
    } else if (isSneaking && sneakingState === 3) {
        player.sneakingState = 2;
    } else if (!isSneaking && sneakingState > 1) {
        player.sneakingState = 1;
    } else if (!isSneaking && sneakingState === 1) {
        player.sneakingState = 0;
    }

}


const BLOCK_OUTLINES = {
    "mythicus_tw:hd": 5,
    "mythicus_tw:crafter": 5,
    "mythicus_tw:searcher": 5,
}
function toggleBlockOutline(block) {

    // return if not special block
    if (!block.typeId.startsWith("mythicus_tw")) return;

    // get block outline
    const outline = BLOCK_OUTLINES[block.typeId];
    if (!outline) return;

    // check for existing outline
    let isOutlined = false;
    for (const entity of block.dimension.getEntitiesAtBlockLocation(block.location)) {
        if (entity.typeId === "mythicus_tw:outline") {
            isOutlined = true;
            entity.remove();
        }
    }

    // return if outline removed
    if (isOutlined) return;

    // create new outline
    block.dimension.spawnEntity("mythicus_tw:outline", block.bottomCenter()).setProperty("mythicus_tw:radius", outline);

}
