import * as mc from "@minecraft/server";
import * as ui from "@minecraft/server-ui";
import * as config from "../sgs_cake_config";
import { highlightBlock, itemManager } from "../sgs_cake_lib";
import * as blocklib from "../sgs_cake_block_lib";
import { openMenu } from "../sgs_cake_guidebook";

const BLOCK_ENTITY = "sgs_cake:teapot_ent";
const RECIPES = config.TEAPOT_RECIPES;

//when adding an ingredient
const RECIPE_ADD_SOUND = "sgs_cake.sfx_teapot_add";
//when processing a recipe
const CRAFT_ANIMATION = "craft";
const CRAFT_SOUND = "sgs_cake.sfx_teapot_process";
const CRAFT_PARTICLE = "sgs_cake:splash_bowl";
//when crafting finishes
const FINISH_SOUND = "sgs_cake.sfx_workstation_end_v2";
const FINISH_PARTICLE = "sgs_cake:finish_crafting";
//strings
const MESSAGE_ABORT = "Stop Mixing";
const MESSAGE_NO_RECIPE = "Recipe not found!";
const SOUND_NO_RECIPE = "sgs_cake.sfx_workstation_fail";
const RECIPE_BOOK_TITLE = "Teapot Recipes";

export class teaPotManager {
    static interact(data) {
        const block = data.block;
        const player = data.player;
        const location = block.bottomCenter();

        if (block.permutation.getState("sgs_cake:can_craft") == 0) return;   //station not set up as crafting unit

        const mainhand = player.getComponent(mc.EntityEquippableComponent.componentId).getEquipmentSlot(mc.EquipmentSlot.Mainhand);
        const heldItem = mainhand.getItem();

        if (heldItem?.typeId == "sgs_cake:guidebook") {
            openMenu(player, "sgs_cake:teapot");
            return;
        }

        const display_entity = blocklib.getDisplayEntity(block);
        if (display_entity == undefined) return; //display entity has vanished for some reason, sad to hear it
        if (display_entity.getProperty("sgs_cake:processing") == true) return; //display entity is doing stuff, do not disturb

        if (display_entity.getProperty("sgs_cake:pickup") == true)  //process is finished but requires item to pickup
        {
            if (heldItem?.typeId != "sgs_cake:ceramic_cup") return;

            const result = display_entity.getDynamicProperty("result");
            let amount = display_entity.getDynamicProperty("amount");
            display_entity.setProperty("sgs_cake:pickup", false);
            display_entity.setProperty("sgs_cake:processing", false);
            display_entity.setProperty("sgs_cake:ingredients", 0);
            mc.system.runTimeout(() => {
                const dropItem = new mc.ItemStack(result, amount);
                const itemEntity = block.dimension.spawnItem(dropItem, player.location);
                itemEntity.clearVelocity();
            }, 1)
            if (player.getGameMode() != mc.GameMode.Creative) mainhand.setItem(itemManager.reduceAmount(heldItem, 1));
            block.dimension.playSound("random.pop", location);
            return;
        }

        //block entity present
        const inventory = display_entity.getComponent('minecraft:inventory').container;

        //add more to the recipe
        if (heldItem == undefined) return;
        player.dimension.playSound(RECIPE_ADD_SOUND, location);

        if (inventory.emptySlotsCount > 0) //inventory slots available, fill those first
        {
            const addItem = heldItem.clone();
            addItem.amount = 1;
            inventory.setItem(inventory.emptySlotsCount - 1, addItem);
            display_entity.setProperty("sgs_cake:ingredients", inventory.size - inventory.emptySlotsCount);
            if (player.getGameMode() != mc.GameMode.Creative) mainhand.setItem(itemManager.reduceAmount(heldItem, 1));
        }
        if (inventory.emptySlotsCount == 0) //inventory is full, start crafting or reset
        {

            const recipe = blocklib.checkRecipe(inventory, RECIPES);
            if (recipe == undefined) //no recipe found
            {
                player.onScreenDisplay.setActionBar(MESSAGE_NO_RECIPE);
                player.dimension.playSound(SOUND_NO_RECIPE, location);
                blocklib.returnItems(block, display_entity, inventory);
                return;
            }
            //recipe found, play crafting animation
            display_entity.playAnimation(CRAFT_ANIMATION);
            block.dimension.playSound(CRAFT_SOUND, location);

            block.dimension.spawnParticle("sgs_cake:pan_embers", block.bottomCenter());
            block.dimension.spawnParticle("sgs_cake:smoke_teapot", block.bottomCenter());

            display_entity.setProperty("sgs_cake:processing", true);

            let pickup = true;
            if (recipe.pickup_item == undefined) pickup = false;

            blocklib.returnContainterItemsInventory(player, inventory); //return container items based on items used from inventory

            mc.system.runTimeout(() => {

                if (recipe.result[0].id != undefined) {
                    display_entity.setDynamicProperty("result", recipe.result[0].id);
                    display_entity.setDynamicProperty("amount", recipe.result[0].amount);
                }
                else {
                    display_entity.setDynamicProperty("result", recipe.result[0]);
                    display_entity.setDynamicProperty("amount", 1);
                }

                if (pickup) {
                    display_entity.setProperty("sgs_cake:pickup", true);

                }
                else {
                    const dropItem = new mc.ItemStack(recipe.result[0], 1);
                    const itemEntity = block.dimension.spawnItem(dropItem, block.center());
                    itemEntity.clearVelocity();
                }

                if (mc.world.scoreboard.getObjective("sgs_cake_settings").getScore("CRAFTSOUND") == 1) block.dimension.playSound(FINISH_SOUND, location);
                block.dimension.spawnParticle(FINISH_PARTICLE, block.bottomCenter());

                display_entity.setProperty("sgs_cake:processing", false);
                display_entity.setProperty("sgs_cake:ingredients", 0);
            }, recipe.time)
        }
    }

    static onplace(data) {
        const block = data.block;
        const below = block.below();
        const location = block.bottomCenter();

        const display_entity = mc.world.getDimension(block.dimension.id).spawnEntity(BLOCK_ENTITY, location);
        const direction = block.permutation.getState("minecraft:cardinal_direction");
        switch (direction) {
            case "north":
                display_entity.setProperty("sgs_cake:rotation", 0);
                break;
            case "east":
                display_entity.setProperty("sgs_cake:rotation", 1);
                break;
            case "south":
                display_entity.setProperty("sgs_cake:rotation", 2);
                break;
            case "west":
                display_entity.setProperty("sgs_cake:rotation", 3);
                break;
            default:
                break;
        }

        if (below.hasTag("sgs_cake_stove_base")) {
            block.setPermutation(block.permutation.withState('sgs_cake:can_craft', 1));;
            below.setPermutation(below.permutation.withState('sgs_cake:crafting_station', 5));
            highlightBlock(block);
            highlightBlock(below);
        }

        if (below.hasTag("sgs_farm_stove_base")) {
            block.setPermutation(block.permutation.withState('sgs_cake:can_craft', 1));
            below.setPermutation(below.permutation.withState('sgs_farm:crafting_station', 4));
            highlightBlock(block);
            highlightBlock(below);
        }
    }

    static destroy(data) {
        const block = data.block;
        const below = block.below();
        if (below.hasTag("sgs_cake_stove_base")) {
            below.setPermutation(below.permutation.withState('sgs_cake:crafting_station', 0));
        }
        blocklib.clearDisplay(block);
    }

    static recipeMenu(player) {
        let recipe_string = "";
        for (let index = 0; index < RECIPES.length; index++) {
            const element = RECIPES[index];
            recipe_string = recipe_string + element.display + "\n\n";
        }

        mc.system.runTimeout(() => {
            ui.uiManager.closeAllForms(player);
            player.playSound("item.book.page_turn", { pitch: 1.0, volume: 5.0, });

            const menu = new ui.ActionFormData();
            menu.title(RECIPE_BOOK_TITLE);
            menu.body(recipe_string);

            menu.show(player).then(result => {
                if (result.canceled) return;
            });

        }, 0)
        return;
    };
}

