import { EntityComponentTypes, ItemStack } from "@minecraft/server";
import { npcs } from "../data/npcs";
import { ActionFormData } from "@minecraft/server-ui";
import { fixName } from "../other/utils";
export class NPC {
    static isNPC(entity) {
        //check the id and then the location of it
        //test if the entity is an npc
        if (entity.typeId == "model:npc_custom") {
            //test location of the entity to see if it matches any of the npcs
            for (const npc of npcs) {
                if (Math.floor(entity.location.x) == Math.floor(npc.location.x) &&
                    Math.floor(entity.location.y) == Math.floor(npc.location.y) &&
                    Math.floor(entity.location.z) == Math.floor(npc.location.z)) {
                    return true;
                }
            }
            return false;
        }
        return false;
    }
    static getNpc(entity) {
        for (const npc of npcs) {
            if (Math.floor(entity.location.x) == Math.floor(npc.location.x) &&
                Math.floor(entity.location.y) == Math.floor(npc.location.y) &&
                Math.floor(entity.location.z) == Math.floor(npc.location.z)) {
                return npc;
            }
        }
        return undefined;
    }
    static getTasks(entity) {
        //get the tasks of the entity
        for (const npc of npcs) {
            if (Math.floor(entity.location.x) == Math.floor(npc.location.x) &&
                Math.floor(entity.location.y) == Math.floor(npc.location.y) &&
                Math.floor(entity.location.z) == Math.floor(npc.location.z)) {
                return npc.tasks;
            }
        }
        return undefined;
    }
    static getNpcId(entity) {
        for (const npc of npcs) {
            if (Math.floor(entity.location.x) == Math.floor(npc.location.x) &&
                Math.floor(entity.location.y) == Math.floor(npc.location.y) &&
                Math.floor(entity.location.z) == Math.floor(npc.location.z)) {
                return npc.id;
            }
        }
        return undefined;
    }
    static getTaskLevel(player, entity) {
        const npcId = this.getNpcId(entity);
        if (!npcId)
            return 0;
        const tagPrefix = `${npcId}_`;
        const tags = player.getTags();
        for (const tag of tags) {
            if (tag.startsWith(tagPrefix)) {
                const level = parseInt(tag.substring(tagPrefix.length), 10);
                if (!isNaN(level)) {
                    return level;
                }
            }
        }
        player.addTag(`${npcId}_0`);
        return 0;
    }
    static hasItems(player, task) {
        const invComp = player.getComponent(EntityComponentTypes.Inventory);
        if (invComp == undefined)
            return false;
        const inventory = invComp.container;
        if (inventory == undefined)
            return false;
        for (let i = 0; i < inventory.size; i++) {
            const item = inventory.getItem(i);
            if (item == undefined)
                continue;
            if (item.typeId == task.needs.item && item.amount >= task.needs.amount) {
                return true;
            }
        }
        return false;
    }
    static increaseTaskLevel(player, entity) {
        const npcId = this.getNpcId(entity);
        if (!npcId)
            return;
        const tagPrefix = `${npcId}_`;
        const tags = player.getTags();
        let level = 0;
        for (const tag of tags) {
            if (tag.startsWith(tagPrefix)) {
                level = parseInt(tag.substring(tagPrefix.length), 10);
                if (!isNaN(level)) {
                    player.removeTag(tag);
                    break;
                }
            }
        }
        player.addTag(`${npcId}_${level + 1}`);
    }
}
function completedTasks(player, npc) {
    //this menu is for when the user has done all the tasks
    const form = new ActionFormData();
    form.title(`${npc.name}`);
    form.body(`You have completed all the tasks for §9${npc.name}§7!\n\nPlease find another NPC to complete more tasks.`);
    form.button("§l§cExit Menu§r\n§8Click Here");
    form.show(player).then(data => {
        if (data.canceled || data.selection == undefined)
            return;
    });
}
export function handleNPMenu(player, npc, task, entity) {
    if (!task)
        return completedTasks(player, npc);
    const form = new ActionFormData()
        .title(`${npc.name}'s Mission!`)
        .body(`§7Information:\n§8${task.description}.\n\n§gNeeds:\n§7Item: §8${task.needs.name}\n§7Amount: §8x${task.needs.amount}\n\n§bYou will receive:\n§7Item: §8${task.rewards.name}s\n§7Amount: §8x${task.rewards.amount}§r\n\n§8Complete the task to earn a reward.\n\n§7Press the give item(s) button to give the required item(s) to this NPC.`)
        .button("§9Give Item(s)\n§8Click Here")
        .button("§l§cExit Menu§r\n§8Click Here");
    form.show(player).then(data => {
        if (data.canceled || data.selection === undefined || data.selection === 1)
            return;
        if (!NPC.hasItems(player, task)) {
            player.sendMessage("§8[§6!§8] §cYou do not have the required items to complete this task!\n§8Please come back when you have the required items.");
            return;
        }
        const invComp = player.getComponent(EntityComponentTypes.Inventory);
        if (!invComp)
            return;
        const inventory = invComp.container;
        if (!inventory)
            return;
        for (let i = 0; i < inventory.size; i++) {
            const item = inventory.getItem(i);
            if (!item)
                continue;
            if (item.typeId === task.needs.item && item.amount >= task.needs.amount) {
                if (item.amount === task.needs.amount) {
                    inventory.setItem(i, undefined);
                }
                else {
                    item.amount -= task.needs.amount;
                    inventory.setItem(i, item);
                }
                break; // Exit the loop once the required item is found and processed
            }
        }
        player.sendMessage(`§8[§6!§8] §7You have completed the task for §9${npc.name}§7!\n§7You have been rewarded §9${task.rewards.amount}x ${fixName(task.rewards.item)}(s)§7.`);
        const rewardItem = new ItemStack(task.rewards.item, task.rewards.amount);
        inventory.addItem(rewardItem);
        // Increase the task level
        NPC.increaseTaskLevel(player, entity);
    });
}
