import { ItemStack } from "@minecraft/server";
import FSUtil from "../FSUtil";
import { AUTOMATIC_ITEM_LORE_TEXT, LOG_DYNAMIC_PROPERTY_WRITES } from "../FSConstants";
import FSLocalizedString from "../FSLocalizedString";
export class FSInventoryItem {
    constructor(slot, name, amount, item, options) {
        this.slot = slot;
        this.name = name;
        this.amount = amount;
        this.item = item;
    }
}
export default class FSInventoryManager {
    static getInventory(player) {
        let cleanInventory = new Array();
        if (!player) {
            return [];
        }
        let inventory = player.getComponent("minecraft:inventory");
        if (!inventory) {
            return [];
        }
        let container = inventory.container;
        if (!container) {
            return [];
        }
        for (let slot = 0; slot < container.size; slot++) {
            let item = container.getItem(slot);
            if (item) {
                cleanInventory.push(new FSInventoryItem(slot, item.typeId, item.amount, item, {}));
            }
            else {
                cleanInventory.push(new FSInventoryItem(slot, "empty", 0, null, {}));
            }
        }
        return cleanInventory;
    }
    static isHoldingItem(player, item) {
        if (!FSInventoryManager.hasItem(player, item, 1)) {
            return false;
        }
        const tag = `57_sbunk_holding_${item}`;
        let command = `/tag @s[hasitem={item=${item},location=slot.weapon.mainhand}] add ${tag}`;
        player.runCommand(command);
        const holdingItem = player.hasTag(tag);
        player.removeTag(tag);
        return holdingItem;
    }
    static hasItem(player, item, amount = 1) {
        amount = Math.max(0, amount);
        item = item.toLowerCase();
        if (!player) {
            return false;
        }
        if (item.indexOf(":") === -1) {
            item = "minecraft:" + item;
            console.error(`[WARN] Item name "${item}" does not have a namespace, added "minecraft:" namespace.`);
        }
        let inventory = FSInventoryManager.getInventory(player);
        let count = 0;
        for (let i = 0; i < inventory.length; i++) {
            if (inventory[i].name === item) {
                count += inventory[i].amount;
            }
        }
        return count >= amount;
    }
    static calculateItemShortage(player, item, wantAmount) {
        wantAmount = Math.max(0, wantAmount);
        item = item.toLowerCase();
        if (!player) {
            return 0;
        }
        if (item.indexOf(":") === -1) {
            item = "minecraft:" + item;
            console.error(`[WARN] Item name "${item}" does not have a namespace, added "minecraft:" namespace.`);
        }
        let inventory = FSInventoryManager.getInventory(player);
        let count = 0;
        for (let i = 0; i < inventory.length; i++) {
            if (inventory[i].name === item) {
                count += inventory[i].amount;
            }
        }
        return wantAmount - count;
    }
    static getCountOfItem(player, item) {
        item = item.toLowerCase();
        if (!player) {
            return 0;
        }
        if (item.indexOf(":") === -1) {
            item = "minecraft:" + item;
            console.error(`[WARN] Item name "${item}" does not have a namespace, added "minecraft:" namespace.`);
        }
        let inventory = FSInventoryManager.getInventory(player);
        let count = 0;
        for (let i = 0; i < inventory.length; i++) {
            if (inventory[i].name === item) {
                count += inventory[i].amount;
            }
        }
        return count;
    }
    static removeItem(player, item, amount) {
        amount = Math.max(0, amount);
        item = item.toLowerCase();
        if (!player) {
            return false;
        }
        if (!FSInventoryManager.hasItem(player, item, amount)) {
            return false;
        }
        var removed = 0;
        let inventory = FSInventoryManager.getInventory(player);
        let minecraftInventory = player.getComponent("minecraft:inventory");
        let minecraftContainer = minecraftInventory.container;
        for (let i = 0; i < inventory.length; i++) {
            if (inventory[i].name === item) {
                if (inventory[i].amount >= amount - removed) {
                    var newAmount = inventory[i].amount - (amount - removed);
                    if (newAmount > 0) {
                        inventory[i].item.amount = newAmount;
                        minecraftContainer.setItem(inventory[i].slot, inventory[i].item);
                    }
                    else {
                        minecraftContainer.setItem(inventory[i].slot, undefined);
                    }
                    removed = amount;
                    break;
                }
                else {
                    removed += inventory[i].amount;
                    minecraftContainer.setItem(inventory[i].slot, undefined); 
                }
            }
        }
        if (removed < amount) {
            return false;
        }
        else {
            return true;
        }
    }
    static removeItemWithSerialNumber(player, serialNumber) {
        if (!player) {
            return false;
        }
        if (!serialNumber || serialNumber === "") {
            return false;
        }
        let inventory = FSInventoryManager.getInventory(player);
        let minecraftInventory = player.getComponent("minecraft:inventory");
        let minecraftContainer = minecraftInventory.container;
        for (let i = 0; i < inventory.length; i++) {
            let item = inventory[i].item;
            if (item) {
                let itemSerialNumber = FSInventoryManager.getSerialNumber(item);
                if (itemSerialNumber === serialNumber) {
                    minecraftContainer.setItem(inventory[i].slot, undefined);
                    return true;
                }
            }
        }
        return false;
    }
    static getSerialNumber(item) {
        return item.getDynamicProperty(FSUtil.namespacedStringCr("item_serial_number")) || "";
    }
    static assignSerialNumber(item) {
        const sn = FSUtil.uuid();
        if (LOG_DYNAMIC_PROPERTY_WRITES) {
            console.error(`Setting dynamic property: ${FSUtil.namespacedString("item_serial_number", "_")} = ${sn}`);
        }
        item.setDynamicProperty(FSUtil.namespacedStringCr("item_serial_number"), sn);
        return sn;
    }
    static replaceItemInHand(player, item, amount) {
        return false;
        amount = Math.max(0, amount);
        item = item.toLowerCase();
        if (!player) {
            return false;
        }
        if (amount <= 0 || amount > 256) {
            console.error("Invalid amount of items to add: " + amount);
            return false;
        }
        let command = `/replaceitem entity @s slot.weapon.mainhand 0 ${item} ${amount}`;
        player.runCommand(command);
        return true;
    }
    static addItem(player, item, amount, injectMetaData = true) {
        try {
            amount = Math.max(0, amount);
            item = item.toLowerCase();
            if (!player) {
                return false;
            }
            if (amount <= 0 || amount > 256) {
                console.error("Invalid amount of items to add: " + amount);
                return false;
            }
            let inventory = FSInventoryManager.getInventory(player);
            var added = 0;
            let minecraftInventory = player.getComponent("minecraft:inventory");
            let minecraftContainer = minecraftInventory.container;
            for (let i = 0; i < inventory.length; i++) {
                if (inventory[i].name === item) {
                    if (inventory[i].amount + amount <= 64) {
                        inventory[i].item.amount += amount;
                        if (AUTOMATIC_ITEM_LORE_TEXT.length >= 1) {
                            inventory[i].item.setLore([AUTOMATIC_ITEM_LORE_TEXT]); 
                        }
                        minecraftContainer.setItem(inventory[i].slot, inventory[i].item);
                        added = amount;
                        break;
                    }
                    else {
                        added += 64 - inventory[i].amount;
                        inventory[i].item.amount = 64;
                        if (AUTOMATIC_ITEM_LORE_TEXT.length >= 1) {
                            inventory[i].item.setLore([AUTOMATIC_ITEM_LORE_TEXT]); 
                        }
                        minecraftContainer.setItem(inventory[i].slot, inventory[i].item);
                    }
                }
            }
            if (added < amount) {
                for (let i = 0; i < inventory.length; i++) {
                    if (inventory[i].name === "empty") {
                        let itemStack = new ItemStack(item, Math.min(amount - added, 64));
                        if (injectMetaData && itemStack.amount === 1) {
                            if (LOG_DYNAMIC_PROPERTY_WRITES) {
                                console.error(`Setting dynamic property: ${FSUtil.namespacedString("item_serial_number", "_")} = ${FSUtil.uuid()}`);
                            }
                            itemStack.setDynamicProperty(FSUtil.namespacedStringCr("item_serial_number"), FSUtil.uuid());
                        }
                        minecraftContainer.setItem(inventory[i].slot, itemStack);
                        if (AUTOMATIC_ITEM_LORE_TEXT.length >= 1) {
                            itemStack.setLore([AUTOMATIC_ITEM_LORE_TEXT]); 
                        }
                        added += itemStack.amount;
                        if (added >= amount) {
                            break;
                        }
                    }
                }
            }
            return added === amount;
        }
        catch (error) {
            return false;
        }
    }
    static addItemWithProps(player, item, props, options) {
        let minecraftInventory = player.getComponent("minecraft:inventory");
        let minecraftContainer = minecraftInventory.container;
        let itemStack = new ItemStack(item);
        options = options || {};
        for (let key in props) {
            let cleanKey = key;
            if (key.indexOf(":") !== -1) {
                cleanKey = key.split(":")[1];
            }
            if (LOG_DYNAMIC_PROPERTY_WRITES) {
                console.error(`Setting dynamic property: ${FSUtil.namespacedString(cleanKey, "_")} = ${props[key]}`);
            }
            itemStack.setDynamicProperty(FSUtil.namespacedStringCr(cleanKey), props[key]);
        }
        let serialNumber = FSUtil.uuid();
        if (options && options.forceItemSerialNumber) {
            serialNumber = options.forceItemSerialNumber || "";
        }
        if (LOG_DYNAMIC_PROPERTY_WRITES) {
            console.error(`Setting dynamic property: ${FSUtil.namespacedString("item_serial_number", "_")} = ${serialNumber}`);
        }
        itemStack.setDynamicProperty(FSUtil.namespacedStringCr("item_serial_number"), serialNumber);
        options = options || {};
        if (options.name) {
            itemStack.nameTag = options.name || "";
        }
        if (AUTOMATIC_ITEM_LORE_TEXT.length >= 1) {
            if (options.lore) {
                options.lore.unshift(AUTOMATIC_ITEM_LORE_TEXT);
            }
            else {
                options.lore = [AUTOMATIC_ITEM_LORE_TEXT];
            }
        }
        if (options.lore) {
            itemStack.setLore(options.lore || []);
        }
        if (options.preferredSlot === -1) {
            delete options.preferredSlot;
        }
        try {
            if (options.preferredSlot) {
                let itemInPreferredSlot = minecraftContainer.getItem(options.preferredSlot);
                if (itemInPreferredSlot) {
                    for (let i = 0; i < minecraftContainer.size; i++) {
                        if (i !== options.preferredSlot) {
                            let itemInSlot = minecraftContainer.getItem(i);
                            if (!itemInSlot) {
                                minecraftContainer.setItem(i, itemInPreferredSlot);
                                break;
                            }
                        }
                    }
                }
                let added = minecraftContainer.setItem(options.preferredSlot, itemStack);
                return serialNumber;
            }
            else {
                let added = minecraftContainer.addItem(itemStack);
            }
            return serialNumber;
        }
        catch (ex) {
            console.error(ex);
            return "";
        }
    }
    static hasInventorySpaceAvailable(player, numSlotsRequired = 1, outputNotEnoughInventorySpaceMessage = false) {
        let inventory = FSInventoryManager.getInventory(player);
        let emptySlots = 0;
        for (let i = 0; i < inventory.length; i++) {
            if (inventory[i].name === "empty") {
                emptySlots++;
            }
        }
        if (emptySlots < numSlotsRequired && outputNotEnoughInventorySpaceMessage) {
            const message = {
                rawtext: [
                    {
                        translate: FSLocalizedString.localize("inventory.space.not_enough", "§l§c[!]§r Not enough inventory space!", "Message to player when they do not have enough inventory space")
                    }
                ]
            };
            player.sendMessage(message);
            player.playSound("fs.sbunk.chat_ping");
        }
        return emptySlots >= numSlotsRequired;
    }
    static hasHotbarSpaceAvailable(player, numSlotsRequired = 1) {
        let inventory = FSInventoryManager.getInventory(player);
        let emptySlots = 0;
        for (let i = 0; i < 9; i++) {
            if (inventory[i].name === "empty") {
                emptySlots++;
            }
        }
        return emptySlots >= numSlotsRequired;
    }
    static giveItem(player, item, amount) {
        return FSInventoryManager.addItem(player, item, amount);
    }
    static giveItemWithProps(player, item, props, options) {
        return FSInventoryManager.addItemWithProps(player, item, props, options);
    }
    static takeItem(player, item, amount) {
        return FSInventoryManager.removeItem(player, item, amount);
    }
}

//# sourceMappingURL=../../../../../_SBUNK_BPDebug/fs_sbunk/fs/libs/FSInventoryManager.js.map
