import { EntityInventoryComponent, ItemStack, world } from "@minecraft/server";
import Buffer from "../../_Utilities/Buffer";
import { MinecraftBlockTypes } from "../../_Utilities/vanilla-data/mojang-block";
import Block_Inventory_Manager from "../../Block/Managers/Block_Inventory_Manager";
import Item_Manager from "../../Item/Item_Manager";
export default class Entity_Inventory_Manager {
    static get(entity) {
        const inventory = new Array();
        const container = this.container(entity);
        if (container == undefined)
            return undefined;
        for (let i = 0; i < container.size; ++i) {
            inventory.push(container.getItem(i));
        }
        return inventory;
    }
    static get_Item(entity, slot) {
        const container = this.container(entity);
        if (container == undefined)
            return undefined;
        return container.getItem(slot);
    }
    static set(entity, inventory) {
        const container = this.container(entity);
        if (container == undefined)
            return undefined;
        for (let i = 0; i < container.size; ++i) {
            this.set_Item(entity, i, inventory[i]);
        }
    }
    static set_Item(entity, slot, item) {
        const container = this.container(entity);
        if (container == undefined)
            return undefined;
        if (item == undefined) {
            container.setItem(slot);
        }
        else if (item instanceof ItemStack) {
            container.setItem(slot, item);
        }
        else {
            container.setItem(slot, Item_Manager.new(item));
        }
    }
    static add_Item(entity, item) {
        const container = this.container(entity);
        if (container == undefined)
            return undefined;
        if (item instanceof ItemStack) {
            container.addItem(item);
        }
        else {
            container.addItem(Item_Manager.new(item));
        }
    }
    static clear(entity) {
        const container = this.container(entity);
        if (container == undefined)
            return undefined;
        this.container(entity).clearAll();
    }
    static clear_Item(entity, item_ID) {
        const inventory = this.get(entity);
        for (let i = 0; i < inventory.length; ++i) {
            if (inventory[i] == undefined)
                continue;
            if (inventory[i].typeId != item_ID)
                continue;
            this.set_Item(entity, i);
        }
    }
    static reduce(entity, item_ID, amount) {
        const inventory = this.get(entity);
        if (this.count_Item(entity, item_ID) < amount)
            return false;
        let count = amount;
        for (let i = 0; i < inventory.length; ++i) {
            if (inventory[i] == undefined)
                continue;
            if (inventory[i].typeId != item_ID)
                continue;
            const item = inventory[i];
            if (item.amount > count) {
                item.amount = item.amount - count;
                this.set_Item(entity, i, item);
                break;
            }
            else {
                count = count - item.amount;
                this.set_Item(entity, i);
            }
        }
        return true;
    }
    static count_Item(entity, item_ID) {
        const inventory = this.get(entity);
        let amount = 0;
        for (let i = 0; i < inventory.length; ++i) {
            if (inventory[i] == undefined)
                continue;
            if (inventory[i].typeId != item_ID)
                continue;
            amount = amount + inventory[i].amount;
        }
        return amount;
    }
    static empty_Slots(entity) {
        return this.container(entity).emptySlotsCount;
    }
    static save(entity) {
        const inventory = this.get(entity);
        const bounds = entity.dimension.heightRange.min;
        const start = { x: entity.location.x, y: bounds + 2, z: entity.location.z };
        const end = { x: start.x, y: start.y, z: start.z };
        let offset = 0;
        for (let i = 0; i < Math.ceil(inventory.length / 27); i++) {
            entity.dimension.setBlockType(end, MinecraftBlockTypes.Chest);
            const chest = entity.dimension.getBlock(end);
            for (let j = 0; j < 27; j++) {
                Block_Inventory_Manager.set_Item(chest, j, inventory[j + offset]);
            }
            end.y = end.y + 1;
            offset = offset + 27;
        }
        const id = "bgs:" + entity.id;
        world.structureManager.createFromWorld(id, entity.dimension, start, end);
        for (let i = 0; i < Math.ceil(inventory.length / 27); i++) {
            entity.dimension.setBlockType(start, MinecraftBlockTypes.Air);
            start.y = start.y + 1;
        }
        Buffer.set_Data("3cf8e83a-3bf8-40a9-94a6-ea99ab052e4e", id, inventory);
        return true;
    }
    static load(entity) {
        const bounds = entity.dimension.heightRange.min;
        const location = { x: entity.location.x, y: bounds + 2, z: entity.location.z };
        const id = "bgs:" + entity.id;
        const data = Buffer.get_Data("3cf8e83a-3bf8-40a9-94a6-ea99ab052e4e", id);
        if (data != undefined) {
            this.set(entity, data);
            return true;
        }
        const structure = world.structureManager.get(id);
        if (structure == undefined)
            return false;
        world.structureManager.place(structure, entity.dimension, location);
        const inventory = new Array();
        for (let i = 0; i < 16; i++) {
            const chest = entity.dimension.getBlock(location);
            if (chest.typeId != MinecraftBlockTypes.Chest)
                break;
            const items = Block_Inventory_Manager.get(chest);
            for (let j = 0; j < 27; j++) {
                inventory.push(items[j]);
            }
            location.y = location.y + 1;
        }
        this.set(entity, inventory);
        for (let i = 0; i < 16; i++) {
            const chest = entity.dimension.getBlock(location);
            if (chest.typeId != MinecraftBlockTypes.Chest)
                break;
            entity.dimension.setBlockType(location, MinecraftBlockTypes.Air);
            location.y = location.y + 1;
        }
        Buffer.set_Data("3cf8e83a-3bf8-40a9-94a6-ea99ab052e4e", id, inventory);
        return true;
    }
    static delete(entity) {
        const id = "bgs:" + entity.id;
        world.structureManager.delete(id);
        Buffer.delete_Data("3cf8e83a-3bf8-40a9-94a6-ea99ab052e4e", id);
    }
    static container(entity) {
        return entity.getComponent(EntityInventoryComponent.componentId).container;
    }
}
