import { ActionFormData, ModalFormData } from "@minecraft/server-ui";
import { ItemStack, system, world } from "@minecraft/server";
import * as utils from "../utils";
import * as inventory_utils from "../inventory_utils";
import * as gld from "../gld";
import * as wallet from "../wallet"
import { showApp as main_menu, checkDepletedBattery } from "./main_menu"; 

const bankAppName = gld.getAppData("bank");

export async function showApp(player){
    if (await checkDepletedBattery(player))
        return;

    let depositDirt = 0;
    let depositSand = 0;
    let depositStone = 0;
    let depositCopper = 0;
    let depositIron = 0;
    let depositGold = 0;
    let depositDiamond = 0;
    let depositEmerald = 0;
    let depositNetherite = 0;
    let noDirtMessage = "";
    let noSandMessage = "";
    let noStoneMessage = "";
    let noCopperMessage = "";
    let noIronMessage = "";
    let noGoldMessage = "";
    let noDiamondMessage = "";
    let noEmeraldMessage = "";
    let noNetheriteMessage = "";

    let dirtStacks = 0;
    let sandStacks = 0;
    let stoneStacks = 0;

    let dirtInInventory = await inventory_utils.countItemInInventory(player, "minecraft:dirt");
    let sandInInventory = await inventory_utils.countItemInInventory(player, "minecraft:sand");
    let stoneInInventory = await inventory_utils.countItemInInventory(player, "minecraft:cobblestone");

    let copperInInventory = await inventory_utils.countItemInInventory(player, "minecraft:raw_copper");
    let ironInInventory = await inventory_utils.countItemInInventory(player, "minecraft:raw_iron");
    let goldInInventory = await inventory_utils.countItemInInventory(player, "minecraft:raw_gold");
    let diamondInInventory = await inventory_utils.countItemInInventory(player, "minecraft:diamond");
    let emeraldInInventory = await inventory_utils.countItemInInventory(player, "minecraft:emerald");
    let netheriteInInventory = await inventory_utils.countItemInInventory(player, "minecraft:netherite_scrap");

    if(dirtInInventory < 64 ) {
        noDirtMessage = "§c(0 item stacks)"
    } else {
        dirtStacks = Math.round(dirtInInventory/64);
        noDirtMessage = `(0-${dirtStacks} ${stackName(dirtStacks,false)})`
    }
    if(sandInInventory < 64 ) {
        noSandMessage = "§c(0 item stacks)"
    } else {
        sandStacks = Math.round(sandInInventory/64);
        noSandMessage = `(0-${sandStacks} ${stackName(sandStacks,false)})`
    }
    if(stoneInInventory < 64 ) {
        noStoneMessage = "§c(0 item stacks)"
    } else {
        stoneStacks = Math.round(stoneInInventory/64);
        noStoneMessage = `(0-${stoneStacks} ${stackName(stoneStacks,false)})`
    }
    if(copperInInventory === 0 ) {
        noCopperMessage = "§c(0 items)"
    } else {
        noCopperMessage = `(0-${copperInInventory})`
    }
    if(ironInInventory === 0 ) {
        noIronMessage = "§c(0 items)"
    } else {
        noIronMessage = `(0-${ironInInventory})`
    }
    if(goldInInventory === 0 ) {
        noGoldMessage = "§c(0 items)"
    } else {
        noGoldMessage = `(0-${goldInInventory})`
    }
    if(diamondInInventory === 0 ) {
        noDiamondMessage = "§c(0 items)"
    } else {
        noDiamondMessage = `(0-${diamondInInventory})`
    }
    if(emeraldInInventory === 0 ) {
        noEmeraldMessage = "§c(0 items)"
    } else {
        noEmeraldMessage = `(0-${emeraldInInventory})`
    }
    if(netheriteInInventory === 0 ) {
        noNetheriteMessage = "§c(0 items)"
    } else {
        noNetheriteMessage = `(0-${netheriteInInventory})`
    }
    

    const BankApp = new ModalFormData().title(`${bankAppName.name}`)
        .slider(`${gld.getScreenTitle(player)}\n`+
        `Use this app to convert resources into Smartcoins. Set the amount you want to convert and press Submit to complete the exchange.\n\n`+
        `＀§l§2Dirt ${noDirtMessage}§2`, 0, dirtStacks, 1, 0)
        .slider(`＀§l§eSand ${noSandMessage}§e`, 0, sandStacks, 1, 0)
        .slider(`＀§l§7Cobblestone ${noStoneMessage}§7`, 0, stoneStacks, 1, 0)
        .slider(`＀§l§6Raw Copper ${noCopperMessage}§f`, 0, copperInInventory, 1, 0)
        .slider(`＀§l§fRaw Iron ${noIronMessage}§f`, 0, ironInInventory, 1, 0)
        .slider(`＀§l§6Raw Gold ${noGoldMessage}§6`, 0, goldInInventory, 1, 0)
        .slider(`＀§l§bDiamond ${noDiamondMessage}§b`, 0, diamondInInventory, 1, 0)
        .slider(`＀§l§aEmerald ${noEmeraldMessage}§a`, 0, emeraldInInventory, 1, 0)
        .slider(`＀§l§dNetherite Scraps ${noNetheriteMessage}§d`, 0, netheriteInInventory, 1, 0);

    BankApp.show(player).then(formData => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
        if (formData.formValues)
        {
            depositDirt = formData.formValues[0];
            depositSand = formData.formValues[1];
            depositStone = formData.formValues[2];
            depositCopper = formData.formValues[3];
            depositIron = formData.formValues[4];
            depositGold = formData.formValues[5];
            depositDiamond = formData.formValues[6];
            depositEmerald = formData.formValues[7];
            depositNetherite = formData.formValues[8];
            player.playSound("goe_spa:button_click");

            if (depositDirt !== 0 || depositSand !== 0 || depositStone !== 0 || depositCopper !== 0 || depositIron !== 0 || depositGold !== 0 || depositDiamond !== 0 || depositEmerald !== 0 || depositNetherite !== 0) {
                openDepositMessage(player, depositDirt, depositSand, depositStone, depositCopper, depositIron, depositGold, depositDiamond, depositEmerald, depositNetherite);
            } else {
                main_menu(player);
            }
        }   
    });
}

async function openDepositMessage(player, depositDirt, depositSand, depositStone, depositCopper, depositIron, depositGold, depositDiamond, depositEmerald, depositNetherite) {
    let totalCoins = 0;
    let message = gld.getScreenTitle(player) + "\nYou are about to convert:\n";
    let balance = player.getDynamicProperty("goe_spa_coins");

    if (depositDirt > 0) {
        let dirtCoins = depositDirt * gld.deposit_values.dirt;
        message += `  ${depositDirt}x ${stackName(depositDirt,true)} of §2Dirt§r = §6${dirtCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += dirtCoins;
    }
    if (depositSand > 0) {
        let sandCoins = depositSand * gld.deposit_values.sand;
        message += `  ${depositSand}x ${stackName(depositSand,true)} of §eSand§r = §6${sandCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += sandCoins;
    }
    if (depositStone > 0) {
        let stoneCoins = depositStone * gld.deposit_values.stone;
        message += `  ${depositStone}x ${stackName(depositStone,true)} of §8Cobblestone§r = §6${stoneCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += stoneCoins;
    }
    if (depositCopper > 0) {
        let copperCoins = depositCopper * gld.deposit_values.copper;
        message += `  ${depositCopper}x §fRaw Copper§r = §6${copperCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += copperCoins;
    }
    if (depositIron > 0) {
        let ironCoins = depositIron * gld.deposit_values.iron;
        message += `  ${depositIron}x §fRaw Iron§r = §6${ironCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += ironCoins;
    }
    if (depositGold > 0) {
        let goldCoins = depositGold * gld.deposit_values.gold;
        message += `  ${depositGold}x §6Raw Gold§r = §6${goldCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += goldCoins;
    }
    if (depositDiamond > 0) {
        let diamondCoins = depositDiamond * gld.deposit_values.diamond;
        message += `  ${depositDiamond}x §bDiamond§r = §6${diamondCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += diamondCoins;
    }
    if (depositEmerald > 0) {
        let emeraldCoins = depositEmerald * gld.deposit_values.emerald;
        message += `  ${depositEmerald}x §aEmerald§r = §6${emeraldCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += emeraldCoins;
    }
    if (depositNetherite > 0) {
        let netheriteCoins = depositNetherite * gld.deposit_values.netherite;
        message += `  ${depositNetherite}x §dNetherite Scrap§r = §6${netheriteCoins} ${gld.coinSymbol}§r\n`;
        totalCoins += netheriteCoins;
    }
    message += `Total: §6${totalCoins} ${gld.coinSymbol}.\n\n§aBalance after conversion: §6${balance+totalCoins} ${gld.coinSymbol}\n§fPlease confirm the transaction.\n\n`;

    const DepositMessage = new ActionFormData()
        .title(bankAppName.name)
        .body(message)
        .button("§l§aConfirm", "textures/goe/spa/ui/confirm")
        .button("§l§cCancel", "textures/goe/spa/ui/cancel");

    DepositMessage.show(player).then((response) => {
        inventory_utils.replacePhoneIfUIClosed(player, response);
        let playerPressed = response.selection;

        switch (playerPressed) {
            case 0:
                player.playSound("goe_spa:deposit");
                // system.runTimeout(() =>  player.playSound("goe_spa:deposit"), 10);
                system.runTimeout(() =>  player.playSound("goe_spa:purchase"), 10);
                confirmTransaction(player, depositDirt, depositSand, depositStone, depositCopper, depositIron, depositGold, depositDiamond, depositEmerald, depositNetherite, totalCoins);
                break;
            case 1:
                player.playSound("goe_spa:cancel");
                main_menu(player);
                break;
        }
    });
}

async function confirmTransaction(player, depositDirt, depositSand, depositStone, depositCopper, depositIron, depositGold, depositDiamond, depositEmerald, depositNetherite, coins) {
    try {
        let currentCoins = player.getDynamicProperty("goe_spa_coins");
        let newCoinAmount = currentCoins + coins;
        player.setDynamicProperty("goe_spa_coins", newCoinAmount);
        utils.runPlayerCommand(player, `clear @s dirt 0 ${depositDirt*64}`);
        utils.runPlayerCommand(player, `clear @s sand 0 ${depositSand*64}`);
        utils.runPlayerCommand(player, `clear @s cobblestone 0 ${depositStone*64}`);
        utils.runPlayerCommand(player, `clear @s raw_copper 0 ${depositCopper}`);
        utils.runPlayerCommand(player, `clear @s raw_iron 0 ${depositIron}`);
        utils.runPlayerCommand(player, `clear @s raw_gold 0 ${depositGold}`);
        utils.runPlayerCommand(player, `clear @s diamond 0 ${depositDiamond}`);
        utils.runPlayerCommand(player, `clear @s emerald 0 ${depositEmerald}`);
        utils.runPlayerCommand(player, `clear @s netherite_scrap 0 ${depositNetherite}`);
        utils.tellraw(player, "@s", `§e[Info] You gained §6${coins} ${gld.coinSymbol}§e Smartcoins`);
        //utils.tellraw(player, "@s", `§aSmartcoins balance: §6${newCoinAmount} ${gld.coinSymbol}`);
        // player.dimension.spawnParticle("goe_spa:bought", player.location);
        player.dimension.spawnParticle("goe_spa:coins", player.location);
    } catch (error) {
        utils.runPlayerCommand(player,"title @s actionbar §cTransaction failed. Please try again.");
    }
    main_menu(player);
}

function stackName(stackNum, isCapitalised) {
    if(isCapitalised){
        if (stackNum === 1 || stackNum === 0)
            return "Stack";
        return "Stacks";
    } else {
        if (stackNum === 1 || stackNum === 0)
            return "stack";
        return "stacks";
    }
}
