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"; 

const stats = {
    killed_players: "goe_spa_killed_players",
    killed_mobs: "goe_spa_killed_mobs",
    death_count: "goe_spa_death_count",
    days_survived: "goe_spa_days_survived",
    distance_total: "goe_spa_distance_total",
}

export async function showApp(player){
    if (await checkDepletedBattery(player))
        return;
    let survivalStatsData = gld.getAppData("survival_stats");

    // Create layout
    let SurvivalApp = new ActionFormData();
    SurvivalApp.title(survivalStatsData.name);
    SurvivalApp.body(
        gld.getScreenTitle(player) +
        `§3Players killed: §e${getNumber(player, stats.killed_players)} players\n\n` + 
        `§3Mobs killed: §d${getNumber(player, stats.killed_mobs)} mobs\n\n` + 
        `§3Death count: §d${getNumber(player, stats.death_count)} times\n\n` + 
        `§3Days survived: §9${getDaysSurvived(player)} days\n\n` + 
        `§3Blocks traveled: §e${getNumber(player, stats.distance_total).toFixed(0)} blocks\n\n`
    );
    SurvivalApp.button("Back", "textures/goe/spa/ui/back");
    
    // Display app
    SurvivalApp.show(player).then(result => {
        inventory_utils.replacePhoneIfUIClosed(player, result);
        player.playSound("goe_spa:button_click");
        if (result.canceled) return;
    
        if (result.selection == 0)
            main_menu(player);

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

export async function onPlayerSpawn(event) {
    const player = event.player;
    setJoinTime(player);
}

export async function setJoinTime(player) {
    if (player.getDynamicProperty("goe_spa_join_time") !== undefined)
        return; 

    const time = world.getAbsoluteTime();
    player.setDynamicProperty("goe_spa_join_time", time);
}

export async function onEntityDie(event) {
    const deadEntity = event.deadEntity;
    const damagingEntity = event.damageSource.damagingEntity;

    // Reset death timer
    if (deadEntity.typeId === "minecraft:player")
        deadEntity.setDynamicProperty("goe_spa_join_time", 0);

    if (deadEntity.typeId === "minecraft:player")
        handlePlayerDied(deadEntity);
    
    if (!damagingEntity || damagingEntity.typeId !== "minecraft:player")
        return;

    if (deadEntity.typeId === "minecraft:player")
        handlePlayerKill(damagingEntity);
    else
        handleMobKill(damagingEntity);
}

function handlePlayerDied(player) {
    const oldStat = getNumber(player, stats.death_count);
    setStat(player, stats.death_count, oldStat + 1);
}

function handlePlayerKill(player) {
    const oldStat = getNumber(player, stats.killed_players);
    setStat(player, stats.killed_mobs, oldStat + 1);
}

function handleMobKill(player) {
    const oldStat = getNumber(player, stats.killed_mobs);
    setStat(player, stats.killed_mobs, oldStat + 1);
}

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

function updateDaysSurvived(player) {
    let joinTime = player.getDynamicProperty("goe_spa_join_time");
    if (joinTime === undefined)
        joinTime = 0;

    ++joinTime;
    player.setDynamicProperty("goe_spa_join_time", joinTime);
}

function getDaysSurvived(player) {
    let joinTime = player.getDynamicProperty("goe_spa_join_time");
    if (joinTime === undefined)
        return 0;

    let days = joinTime / 24000;
    return days.toFixed(1);
}

function getNumber(player, name) {
    const rawValue = getRawStat(player, name);
    if (!rawValue)
        return 0;

    return parseFloat(rawValue);
}

function getRawStat(player, name) {
    return player.getDynamicProperty(name);
}

function setStat(player, name, value) {
    player.setDynamicProperty(name, value);
}