import { ActionFormData, ModalFormData } from "@minecraft/server-ui";
import { system, world, ItemStack, EnchantmentType } 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"; 
import { showApp as finances } from "./bank";

const effectStoreData = gld.getAppData("effect_store");

export async function showApp(player){
    if (await checkDepletedBattery(player))
        return;
    // Set layout
    const EffectStoreForm = new ActionFormData().title(effectStoreData.name);
    EffectStoreForm.body( gld.getScreenTitle(player) + `Use this app to purchase useful effects.\n\n` );

    let removeEffectsCost = 25;
    for (const effect of gld.effects) {
        let baseCost = effect.cost[0];

        let costColor = wallet.canAfford(player, baseCost) ? "§l§a" : "§l§c";
        let perLevelText = effect.cost.length > 1 ? " per level" : "";
        EffectStoreForm.button(`§l§6${effect.name}\n${costColor}Cost: ${baseCost}${gld.coinSymbol}${perLevelText}`, effect.icon);
        if (effect.name === "Clear bad effects")
            removeEffectsCost = effect.baseCost[0];
    }

    EffectStoreForm.button("Back", "textures/goe/spa/ui/back");    

    // Display app
    EffectStoreForm.show(player).then(result => {
        inventory_utils.replacePhoneIfUIClosed(player, result);
        if (result.canceled) return;
    
        player.playSound("goe_spa:button_click");

        if (result.selection < gld.effects.length) {
            if (gld.effects[result.selection].name === "Clear bad effects") {
                player.playSound("goe_spa:boost");
                removeEffects(player, removeEffectsCost);
                showApp(player);
            } else {
                displayEffectPage(player, gld.effects[result.selection]);
            }
            return;
        }
        
        main_menu(player);

    }).catch(error => {
        inventory_utils.replacePhoneIfUIClosed(player);
        utils.debug(error.message);
    });
}

async function displayEffectPage(player, effect) {
    // Set layout
    const EffectStoreForm = new ActionFormData().title(effectStoreData.name);

    EffectStoreForm.body(
        gld.getScreenTitle(player) +
        `§6Effect:§r ${effect.name}\n\n` + 
        `§bSelect level:§r\n` 
    );

    for (let i = 0; i < effect.cost.length; i++) {
        const cost = effect.cost[i];
        const duration = effect.duration[i];
        const minutes = Math.floor(duration / 60);
        const seconds = `${duration % 60}`.padStart(2, "0");
        let costColor = wallet.canAfford(player, cost) ? "§l§a" : "§l§c";
        EffectStoreForm.button(`§l§6Level ${i + 1} (${minutes}:${seconds}) ${costColor}Cost: ${cost}${gld.coinSymbol}§f`, effect.icon);
    }

    EffectStoreForm.button("Back", "textures/goe/spa/ui/back");

    // Display effect page
    EffectStoreForm.show(player).then(async result => {
        inventory_utils.replacePhoneIfUIClosed(player, result);
        if (result.canceled) 
            return;

        // Get dropbox value
        let selected = result.selection;
        if (selected === effect.cost.length) { // Back is selected
            player.playSound("goe_spa:button_click");
            showApp(player);
            return;
        }

        const level = selected + 1;
        let effectName = effect.name;
        if (effectName !== "Clear bad effects") {
            effectName += " " + utils.toRoman(level)
        }
        const cost = effect.cost[selected];
        const duration = effect.duration[selected];

        if (!wallet.canAfford(player, cost)) {
            player.playSound("goe_spa:reject");
            showCantAffordForm(player, effectName, cost);
            return;
        }

        player.playSound("goe_spa:button_click");
        player.playSound("goe_spa:boost");

        // Give effect
        giveEffect(player, effect.name, level, duration);

        // Charge player coins
        wallet.charge(player, cost);
        
        player.playSound("goe_spa:purchase");

        showApp(player);

    }).catch(error => {
        inventory_utils.replacePhoneIfUIClosed(player);
        utils.debug(error.message);
    });
}

async function showCantAffordForm(player, effect, cost) {
    const CantAffordForm = new ActionFormData();
    CantAffordForm.title(effectStoreData.name);
    CantAffordForm.body(
        gld.getScreenTitle(player) +
        `\nNot enough Smartcoins (§6${gld.coinSymbol}§r).\n\n` +
        `  §l§3${effect}§r\n\n` + 
        `§cCost:      ${cost} ${gld.coinSymbol}§r\n` + 
        `§4Missing:   ${cost - wallet.getBalance(player)} ${gld.coinSymbol}§r\n\n`
    );
    CantAffordForm.button("§eGet Smartcoins", gld.getAppData("bank").icon);
    CantAffordForm.button("Back", "textures/goe/spa/ui/back");

    CantAffordForm.show(player).then((response) => {
        player.playSound("goe_spa:button_click");

        if (response.selection == 0) {
            finances(player);
            return;
        }

        showApp(player);
    });
}

function removeEffects(player, cost) {
    let effectsCleared = 0;
    for (const effect of player.getEffects()) {
        // Is bad effect?
        for (let i = 0; i < gld.badEffects.length; i++) {
            if (utils.toSnakeCase(gld.badEffects[i]) !== effect.typeId)
                continue;

            player.removeEffect(effect.typeId);
            utils.tellraw(player, "@s", `${gld.badEffects[i]} effect removed`);
            effectsCleared++;
            break;
        }
    }  
    if (effectsCleared === 0)
        utils.tellraw(player, "@s", `No bad effects found`);
    else
        wallet.charge(player, cost);
}

function giveEffect(player, effectName, level, duration) {
    let effectType = utils.toSnakeCase(effectName);
    player.addEffect(
        effectType,
        duration * 20,
        {
            amplifier: level - 1
        }
    );

    utils.tellraw(player, "@s", `Purchased effect: ${effectName}`);
}