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

const CoinClicker = gld.getAppData("coin_clicker");

export async function showApp(player){
    if (await checkDepletedBattery(player))
        return;
    
    // Create layout
    let generatorLevel = player.getDynamicProperty("goe_spa_generator_level");
    if (generatorLevel === undefined) {
        generatorLevel = 0;
        player.setDynamicProperty("goe_spa_generator_level", generatorLevel);
    }

    const generator = gld.CoinClicker.generator[generatorLevel];

    let coinsGenerated = player.getDynamicProperty("goe_spa_coins_generated");
    if (coinsGenerated === undefined)
        coinsGenerated = 0;

    let CoinClickerApp = new ActionFormData();
    CoinClickerApp.title(CoinClicker.name);
    CoinClickerApp.body(
        gld.getScreenTitle(player) + 
        `The Coin Clicker generates coins,\n` + 
        `even while you're not using your phone.\n\n` +
        `COIN GENERATOR:\n` +
        `Generator level: ${generatorLevel + 1} (generating §61 coin§f every ${generator.rate} seconds).\n` +
        `Note: You can increase the coin generation by upgrading this app.\n\n` +
        "§bCOIN CLICKER:\n" +
        "Generate extra coins by clicking the §6Generate Coins§b button.\n" +
        "You can earn §610 coins§b per Minecraft day by clicking here.\n\n"
    );

    let clickerLevel = player.getDynamicProperty("goe_spa_clicker_level");
    if (clickerLevel === undefined) {
        player.setDynamicProperty("goe_spa_clicker_level", 0);
        clickerLevel = 0;
    }

    let clickCount = player.getDynamicProperty("goe_spa_clicker_count");
    if (clickCount === undefined) {
        player.setDynamicProperty("goe_spa_clicker_count", 0);
        clickCount = 0;
    }

    let clickCoinsCount = player.getDynamicProperty("goe_spa_click_coins_count");
    if (clickCoinsCount === undefined) {
        clickCoinsCount = 0;
        player.setDynamicProperty("goe_spa_click_coins_count", clickCoinsCount);
    }

    const maxClickCoinsReached = clickCoinsCount >= gld.CoinClicker.maxClickCoinsPerDay;
        
    if (!maxClickCoinsReached) {
        const clicksLeft = gld.CoinClicker.requiredClicks[clickerLevel] - clickCount;
        CoinClickerApp.button(`§eGenerate Coins §6[${clicksLeft} clicks]`, "textures/goe/spa/ui/coin_clicker_click_button");
    } else {
        CoinClickerApp.button(`§cGenerate Coins\n[Daily limit reached]`, "textures/goe/spa/ui/coin_clicker_click_button");
    }

    let cost = 0;
    if (generator.upgrade !== undefined) {
        cost = generator.upgrade;
        const costColor = wallet.canAfford(player, cost) ? "§l§a" : "§l§c";
        CoinClickerApp.button(`${costColor}Upgrade to level ${generatorLevel + 2} (cost: ${cost} §6${gld.coinSymbol}${costColor})§r`, "textures/goe/spa/ui/coin_clicker_upgrade");
    }

    CoinClickerApp.button("Back", "textures/goe/spa/ui/back");
    
    // Display app
    CoinClickerApp.show(player).then(result => {
        inventory_utils.replacePhoneIfUIClosed(player, result);
        if (result.canceled) return;

        if (generator.upgrade != undefined && result.selection == 1) {
            if (!wallet.canAfford(player, cost)) {
                player.playSound("goe_spa:reject");
                showCantAffordForm(player, cost);
                return;
            }

            player.playSound("goe_spa:upgrade");

            // Upgrade player earn rate
            wallet.charge(player, cost);
            player.setDynamicProperty("goe_spa_generator_level", generatorLevel + 1);
            showUpgradePage(player, generatorLevel);
            return;
        }

        if (result.selection === 0) {
            if (maxClickCoinsReached) {
                player.playSound("goe_spa:wrong_answer");
                showApp(player);
                return;
            }

            ++clickCount;
            let clickerLevel = player.getDynamicProperty("goe_spa_clicker_level");
            const clicksRequired = gld.CoinClicker.requiredClicks[clickerLevel];
            
            if (clickCount < clicksRequired) {
                player.setDynamicProperty("goe_spa_clicker_count", clickCount);
                player.playSound("goe_spa:button_click");
                showApp(player);
                return;
            }

            player.playSound("goe_spa:deposit");
            wallet.deposit(player, 1);

            player.setDynamicProperty("goe_spa_click_coins_count", clickCoinsCount + 1);

            if (clickerLevel + 1 < gld.CoinClicker.requiredClicks.length) {
                player.setDynamicProperty("goe_spa_clicker_level", clickerLevel + 1);

                // Reset timer
                player.setDynamicProperty("goe_spa_clicks_reset_time", 1200); // 20 min (1200s)
            }

            player.dimension.spawnParticle("goe_spa:coins", player.location);

            player.setDynamicProperty("goe_spa_clicker_count", 0);
            showApp(player);
            return;
        }

        player.playSound("goe_spa:button_click");
        main_menu(player);
    
    }).catch(error => {
        utils.debug(error.message);
    });
}

export async function showUpgradePage(player, oldLevel) {
    let UpgradePage = new ActionFormData();
    UpgradePage.title(CoinClicker.name);
    UpgradePage.body(
        `You have upgraded your Coin Generator to level ${oldLevel + 2}.\n\n` +
        `Previous generation rate: §61 coin§r every §3${gld.CoinClicker.generator[oldLevel].rate} seconds§r.\n\n` +
        `New generation rate: §61 coin§r every §3${gld.CoinClicker.generator[oldLevel + 1].rate} seconds§r.\n`
    );

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

    UpgradePage.show(player).then(result => {
        inventory_utils.replacePhoneIfUIClosed(player, result);
        if (result.canceled) return;

        player.playSound("goe_spa:button_click");
        showApp(player);
    });
}

export async function onTick() {
    for (const player of world.getAllPlayers()) {

        if (!gld.playerOwnsApp(player, "coin_clicker"))
            continue;

        const resetTime = player.getDynamicProperty("goe_spa_clicks_reset_time");
        if (resetTime !== undefined) {
            if (resetTime - 1 === 0) {
                // Reset click counter
                player.setDynamicProperty("goe_spa_clicks_reset_time", undefined);
                player.setDynamicProperty("goe_spa_clicker_count", 0);
                player.setDynamicProperty("goe_spa_clicker_level", 0);
            } else {
                player.setDynamicProperty("goe_spa_clicks_reset_time", resetTime - 1);
            }
        }

        let generatorLevel = player.getDynamicProperty("goe_spa_generator_level");
        if (generatorLevel === undefined) {
            generatorLevel = 0;
            player.setDynamicProperty("goe_spa_generator_level", generatorLevel);
        }

        const generator = gld.CoinClicker.generator[generatorLevel];

        let nextCoinTimeLeft = player.getDynamicProperty("goe_spa_next_coin_time");
        if (nextCoinTimeLeft === undefined) {
            player.setDynamicProperty("goe_spa_next_coin_time", generator.rate);
            continue;
        }

        if (--nextCoinTimeLeft <= 0) {
            wallet.deposit(player, 1);
            //utils.tellraw(player, "@s", "§a+§61 coin§a generated by the §6Coin Generator§a.");

            let coinsGenerated = player.getDynamicProperty("goe_spa_coins_generated");
            if (coinsGenerated === undefined)
                coinsGenerated = 0;

            player.setDynamicProperty("goe_spa_coins_generated", ++coinsGenerated);
            player.setDynamicProperty("goe_spa_next_coin_time", generator.rate);
        } else {
            player.setDynamicProperty("goe_spa_next_coin_time", nextCoinTimeLeft);
        }
    }
}

async function showCantAffordForm(player, cost) {
    const CantAffordForm = new ActionFormData();
    CantAffordForm.title(CoinClicker.name);
    CantAffordForm.body(
        gld.getScreenTitle(player) +
        `\nNot enough Smartcoins (§6${gld.coinSymbol}§r).\n\n` +
        `  §l§6Coin Clicker Level Upgrade§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);
    });
}