import { world, Player, system, GameMode } from "@minecraft/server";
import { ActionFormData, FormCancelationReason, ModalFormData } from "@minecraft/server-ui";
import { sendPlayerMessage, sendAllMessage, config } from "../../config";
import { deadplayers, getScore, lifesteal, revivelist, setScore } from "../../lifesteal";

function agheart(player: Player) {
    const agheart = new ActionFormData()
        .title(`Admin Panel - Heart`)
        .body(`Choose a command!`)
        .button(`Set hearts`, `textures/items/heart_essence.png`)
        .button(`Reset hearts`, `textures/items/heart_fragment.png`)
        .button(`Set maximum hearts`, `textures/items/ls-heart.png`)
        .button(`Kill or revive`, `textures/items/heart_of_life.png`)
        .button(`Set amount of hearts gained/lost`, `textures/items/withdraw_heart.png`)
        .button(`Option to ban ghosts`, `textures/items/diamond_axe.png`)
        .button(`Close`, `textures/ui/realms_red_x.png`);
    agheart.show(player).then(result => {
        switch (result.selection) {
            case 0:
                const players = world.getAllPlayers();

                const agheart_set = new ModalFormData()
                    .title(`Set a player's hearts`)
                    .dropdown(`Choose a player`, players.map(x => x.name))
                    .slider(`Choose a heart count to set them to`, 0, 200, 1);
                agheart_set.show(player).then(result => {
                    const formValues: any[] = result.formValues;
                    const target = players[formValues[0]];
                    const score = getScore(target, `ls-death`);
                    setScore(target, `ls-death`, formValues[1]);
                    sendPlayerMessage(player, `§aSet §f${target.name}'s§a hearts to §f${formValues[1]}.`);
                    if (score == 0) {
                        setScore(target, `ls-death`, +lifesteal.get(`reviveamount`));
                        target.runCommandAsync(`tag @s remove ls-dead`);
                        if (player.getGameMode() === GameMode.spectator) player.setGameMode(GameMode.survival);
                        target.runCommandAsync(`effect @s resistance 5 255 true`);
                        target.runCommandAsync(`effect @s levitation 0 0 true`);
                    }
                });
                break;
            case 1:
                function agheart_reset() {
                    const players = world.getAllPlayers();

                    const agheart_reset = new ModalFormData()
                        .title(`Reset a player's hearts`)
                        .dropdown(`Choose a player`, players.map(x => x.name));
                    agheart_reset.show(player).then(result => {
                        const formValues: any = result.formValues;
                        const target = players[formValues[0]];
                        const score = getScore(target, `ls-death`);
                        setScore(target, `ls-death`, +lifesteal.get(`startamount`));
                        sendPlayerMessage(player, `§aReset §f${target.name}'s§a hearts to §f10.`);
                        if (score == 0) {
                            setScore(target, `ls-death`, +lifesteal.get(`startamount`));
                            target.removeTag(`ls-dead`);
                            if (player.getGameMode() === GameMode.spectator) player.setGameMode(GameMode.survival);
                            target.runCommandAsync(`effect @s resistance 5 255 true`);
                            target.runCommandAsync(`effect @s levitation 0 0 true`);
                        }
                    });
                }
                agheart_reset();
                break;
            case 2:
                function agheart_setmax() {
                    const agheart_setmax = new ModalFormData()
                        .title(`Set the maximum amount of hearts`)
                        .slider(`Choose an amount of hearts to set the max to`, 10, 200, 1);
                    agheart_setmax.show(player).then(result => {
                        const formValues = result.formValues;
                        lifesteal.set(`maxhearts`, `${formValues[0]}`);
                        sendPlayerMessage(player, `§aSet the max hearts to §f${formValues[0]}.`);
                    });
                }
                agheart_setmax();
                break;
            case 3:
                const agheart_kr = new ActionFormData()
                    .title(`Kill or revive`)
                    .button(`Revive a player`, `textures/items/heart_of_life.png`)
                    .button(`Kill a player\n(Set their hearts to 0)`, `textures/items/iron_sword.png`)
                    .button(`Close`, `textures/ui/realms_red_x.png`);
                agheart_kr.show(player).then(result => {
                    switch (result.selection) {
                        case 0:
                            const options = Array.from(deadplayers.keys());

                            if (!options.length) {
                                const errorGui = new ModalFormData()
                                    .title(`Revive GUI`)
                                    .dropdown(`Choose a player to revive`, [`No dead players!`]);
                                errorGui.show(player);
                                return;
                            }

                            function reviveGuiForm() {
                                const reviveGUI = new ModalFormData()
                                    .title(`Revive GUI`)
                                    .textField(`Search for a player`, `e.g GamerDos7511`)
                                    .dropdown(`Choose a player to revive`, options);
                                reviveGUI.show(player).then(result => {
                                    if (result.formValues[0]) {
                                        let search: string[];
                                        for (let x of options) {
                                            if (x.includes(<any>result.formValues[0])) search.push(x);
                                        }
                                        if (!search.length) {
                                            const reviveGuiSearchUnsuccessful = new ModalFormData()
                                                .title(`Revive GUI - Search Error`)
                                                .dropdown(`Choose a player to revive`, [`No players found!`]);
                                            reviveGuiSearchUnsuccessful.show(player).then(() => {
                                                reviveGuiForm();
                                            });
                                            return;
                                        }
                                        const reviveGuiSearch = new ModalFormData()
                                            .title(`Revive GUI - Search`)
                                            .dropdown(`Choose a player to revive`, search);
                                        reviveGuiSearch.show(player).then(result => {

                                            let formValues: any = result.formValues;
                                            let target = options[formValues[1]];

                                            revivelist.set(`${target.toLowerCase()}`, `${target.toLowerCase()}`);
                                            for (let x of deadplayers.keys()) {
                                                if (x.toLowerCase() == target.toLowerCase()) {
                                                    deadplayers.delete(x);
                                                    break;
                                                }
                                            }
                                            player.runCommandAsync(`playsound heart_of_life_sound @a`);
                                            sendAllMessage(`§b${player.name} has revived ${target}`);
                                        });
                                        return;
                                    }

                                    let formValues: any = result.formValues;
                                    let target = options[formValues[1]];

                                    revivelist.set(`${target.toLowerCase()}`, `${target.toLowerCase()}`);
                                    for (let x of deadplayers.keys()) {
                                        if (x.toLowerCase() == target.toLowerCase()) {
                                            deadplayers.delete(x);
                                            break;
                                        }
                                    }
                                    player.runCommandAsync(`playsound heart_of_life_sound @a`);
                                    sendAllMessage(`§b${player.name} has revived ${target}`);
                                });
                            }
                            reviveGuiForm();
                            break;
                        case 1:
                            const playerArray3: Player[] = [];
                            const options3: string[] = [];

                            for (let players of world.getAllPlayers()) {
                                playerArray3.push(players);
                                options3.push(players.name);
                            }
                            const agheart_kr = new ModalFormData()
                                .title(`Kill a player`)
                                .dropdown(`Choose a player`, options3);
                            agheart_kr.show(player).then(result => {
                                let formValues: any = result.formValues;
                                let target = playerArray3[formValues[0]];
                                if (target.hasTag(`ls-dead`)) return sendPlayerMessage(player, `§cThat player is already dead!`);
                                setScore(target, `ls-death`, 0);
                                sendPlayerMessage(player, `§aSet §f${target.name}'s§a hearts to §f0.`);
                            });
                            break;
                    }
                });
                break;
            case 4:
                const heartglGui = new ModalFormData()
                    .title(`HeartGL`)
                    .slider(`Set the hearts lost/gained when killed/killing`, 1, 4, 1)
                    .toggle(`Set hearts lost §7(Turn off to set hearts gained)`);
                heartglGui.show(player).then(result => {
                    if (result.formValues[1] === true) {
                        lifesteal.set(`heartlose`, `${result.formValues[0]}`);

                        sendPlayerMessage(player, `§aSet §fhearts lost§a to §f${result.formValues[0]}`);
                        return;
                    }
                    lifesteal.set(`heartgain`, `${result.formValues[0]}`);

                    sendPlayerMessage(player, `§aSet §fhearts hearts gained§a to §f${result.formValues[0]}`);
                });
                break;
            case 5:
                const banGhostsGui = new ModalFormData()
                    .title(`Ban Ghosts`)
                    .toggle(`If this toggle is on, losing all hearts will ban you, instead of becoming a ghost (Not recommended for worlds, might make the dead player quit)`, JSON.parse(lifesteal.get(`banghosts`)));
                banGhostsGui.show(player).then(result => {
                    lifesteal.set(`banghosts`, `${result.formValues[0]}`);

                    if (result.formValues[0]) sendPlayerMessage(player, `§aTurned §fbanGhosts on`);
                    if (!result.formValues[0]) sendPlayerMessage(player, `§aTurned §fbanGhosts off`);
                });
                break;
            case 6:
                adminPanel(player);
                break;
        }
    });
}

function agutil(player: Player) {
    const agutil = new ActionFormData()
        .title(`Admin Panel - Utility`)
        .button(`Teleport`, `textures/ui/portalBg.png`)
        .button(`Close`, `textures/ui/realms_red_x.png`);
    agutil.show(player).then(result => {
        if (result.selection == 0) {
            const agutil_tp = new ActionFormData()
                .title(`Utility - Teleport`)
                .button(`Teleport to a player`, `textures/ui/FriendsIcon.png`)
                .button(`Teleport to coordinates`, `textures/ui/xyz_axis.png`)
                .button(`Teleport between dimensions`, `textures/ui/portalBg.png`)
                .button(`Close`, `textures/ui/realms_red_x.png`);
            agutil_tp.show(player).then(result => {
                if (result.selection == 0) {
                    const playerArray: Player[] = [];
                    const options: string[] = [];

                    for (let players of world.getAllPlayers()) {
                        playerArray.push(players);
                        options.push(players.name);
                    }

                    const tp_player = new ModalFormData()
                        .title(`Teleport a player`)
                        .dropdown(`Choose a player`, options)
                        .toggle(`Teleport them to you`, false);
                    tp_player.show(player).then(result => {
                        const formValues: any = result.formValues;
                        let target = playerArray[formValues[0]];
                        if (formValues[1] == true) {
                            let location = target.location;
                            player.teleport(location, { dimension: target.dimension });
                            sendPlayerMessage(player, `§aTeleported you to §f${target.name}.`);
                        }
                        else {
                            let location = player.location;
                            target.teleport(location, { dimension: player.dimension });
                            sendPlayerMessage(player, `§aTeleported §f${target.name}§a to you. `);
                        }
                    });
                }
                if (result.selection == 1) {
                    const tp_coords = new ModalFormData()
                        .title(`Teleport to coordinates`)
                        .textField(`Type Coordinates`, `Enter coordinates`);
                    tp_coords.show(player).then(result => {
                        try {
                            player.runCommandAsync(`teleport @s ${result.formValues[0]}`);
                            sendPlayerMessage(player, `§aSuccessfully teleport you to §f${result.formValues[0]}.`);
                        }
                        catch {
                            sendPlayerMessage(player, `§cFailed to teleport you to ${result.formValues[0]}`);
                        }
                    });
                }
                if (result.selection == 2) {
                    let teleportDimensionGui = new ActionFormData()
                        .title(`Teleport dimensions`)
                        .body(`§gYou will teleport to the corresponding coordinates, e.g if you are in the overworld and you travel to the nether, you will be at your coordinates divided by 8`)
                        .button(`The Overworld`)
                        .button(`The Nether`)
                        .button(`The End`)
                        .button(`Close`);
                    teleportDimensionGui.show(player).then(result => {
                        switch (result.selection) {
                            case 0:
                                if (player.dimension.id == `minecraft:overworld`) return sendPlayerMessage(player, `§cYou are already in the Overworld!`);
                                if (player.dimension.id == `minecraft:nether`) player.teleport({ x: player.location.x * 8, y: player.location.y * 8, z: player.location.z * 8 }, { dimension: world.getDimension(`overworld`) });

                                player.teleport({ x: player.location.x, y: player.location.y, z: player.location.z }, { dimension: world.getDimension(`overworld`) });
                                break;
                            case 1:
                                if (player.dimension.id == `minecraft:nether`) return sendPlayerMessage(player, `§cYou are already in the Nether!`);
                                if (player.dimension.id == `minecraft:overworld`) return player.teleport({ x: player.location.x / 8, y: player.location.y / 8, z: player.location.z / 8 }, { dimension: world.getDimension(`nether`) });

                                player.teleport({ x: player.location.x / 8, y: player.location.y / 8, z: player.location.z / 8 }, { dimension: world.getDimension(`nether`) });
                                break;
                            case 2:
                                if (player.dimension.id == `minecraft:the_end`) return sendPlayerMessage(player, `§cYou are already in the End!`);

                                player.teleport({ x: player.location.x, y: player.location.y, z: player.location.z }, { dimension: world.getDimension(`end`) });
                                break;
                        }
                    });
                }
            });
        }
    });
}

export function adminPanel(player: Player) {
    const agMain = new ActionFormData()
        .title(`Admin Panel`)
        .body(`Choose a command!`)
        .button(`Heart Commands`, `textures/items/ls-heart.png`)
        .button(`Utility Commands`, `textures/ui/Wrenches1`)
        .button(`Close`, `textures/ui/realms_red_x.png`);
    agMain.show(player).then(result => {
        if (result.canceled && result.cancelationReason == `UserBusy`) adminPanel(player);
        if (result.selection == 0) {
            agheart(player);
        }
        if (result.selection == 1) {
            agutil(player);
        }
    });
}