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 { showApp as main_menu, checkDepletedBattery } from "./main_menu"; 

const MAX_MEMOS = 10;

const memoData = gld.getAppData("memo");

export async function showApp(player){
    if (await checkDepletedBattery(player))
        return;
    // Set layout
    const MemoForm = new ActionFormData().title(memoData.name);
    MemoForm.body(
        `${gld.getScreenTitle(player)}§r` +
        `This app is your personal notebook. Use this app to write important info that you can read later on. Write anything that is on your mind.\n\n` + 
        `§3Memos:§f\n`
    );

    const playerMemos = await getMemos(player);
    for (const memo of playerMemos) {
        MemoForm.button(`${memo.title}`, "textures/goe/spa/ui/notes");
    }

    MemoForm.button("New Memo", "textures/goe/spa/ui/new");    
    MemoForm.button("Back", "textures/goe/spa/ui/back");    

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

        if (result.selection < playerMemos.length) {
            await displayMemoForm(player, playerMemos[result.selection]);
            return;
        }

        if (result.selection === playerMemos.length) {
            await displayNewMemoForm(player);
            return;
        }
        
        // Back button pressed
        main_menu(player);

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

async function displayNewMemoForm(player) {
    // Set layout
    const MemoForm = new ModalFormData().title(memoData.name);
    
    const headerText = gld.getScreenTitle(player);
    MemoForm.textField(headerText + "§3Memo Title:§f\n(Max 16 characters)", "Enter title here");
    MemoForm.textField("\n§3Memo Text:§f\n(Max 100 characters)", "Enter text here");

    MemoForm.submitButton("Create Memo");

    // Display enchantment page
    MemoForm.show(player).then(async formData => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
        if (formData.canceled || !formData.formValues) 
            return;

        if (formData.formValues[0] === "") {
            showApp(player);
            return;
        }

        player.playSound("goe_spa:send_message");

        await newMemo(player, formData.formValues[0].substring(0, 16), formData.formValues[1]);
        showApp(player);

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

async function showEditMemoForm(player, memo) {
    // Set layout
    const MemoForm = new ModalFormData().title(memoData.name);
    
    const headerText = gld.getScreenTitle(player);
    MemoForm.textField(headerText + "§3Memo Title:§f\n(Max 16 characters)", "Enter title here", memo.title);
    MemoForm.textField("\n§3Memo Text:§f\n(Max 100 characters)", "Enter text here", memo.text);

    MemoForm.submitButton("Save Changes");

    // Display enchantment page
    MemoForm.show(player).then(async formData => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
        if (formData.canceled || !formData.formValues) 
            return;

        if (formData.formValues[0] === "") {
            player.playSound("goe_spa:reject");
            showApp(player);
            return;
        }

        player.playSound("goe_spa:send_message");
        
        await editMemo(player, memo.title, formData.formValues[0].substring(0, 16), formData.formValues[1]);
        showApp(player);

    }).catch(error => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
    });
}

async function showSendMemoForm(player, memo) {
    const ALLPLAYERS = world.getAllPlayers().filter(p => p.name !== player.name);

    // Generate a list of player names for display in the dropdown
    const playerNames = ['All players', ...ALLPLAYERS.map(p => p.name)];

    // Generate a list of indexes corresponding to the players
    // Include a special index for "All players"
    const playerIndexes = [-1, ...ALLPLAYERS.map((_, index) => index)];

    // Set layout
    const SendMemoForm = new ModalFormData().title(memoData.name);
    
    const headerText = gld.getScreenTitle(player);
    SendMemoForm.dropdown(
        `${gld.getScreenTitle(player)}`+ 
        "§aSend to:§r", 
        playerNames, 
        0
    )  // Default to "All players"

    SendMemoForm.submitButton("Send");

    // Display enchantment page
    SendMemoForm.show(player).then(async formData => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
        if (formData.canceled || !formData.formValues) 
            return;

        const selectedIndex = playerIndexes[formData.formValues[0]];

        // Handle the "All players" option
        let sendToSelector = '@a';  // Special value for all players
        if (selectedIndex > -1) {
            sendToSelector = ALLPLAYERS[selectedIndex];
        }

        player.playSound("goe_spa:send_message");

        sendMessage(player, sendToSelector, memo.text);

        main_menu(player);
    }).catch(error => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
    });
}

async function sendMessage(sender, sendTo, msg) {
    if (sendTo === "@a"){
        utils.runPlayerCommand(sender, `msg @a[name=!${sender.name}] ${msg}`);
        main_menu(sender)
    } else {
        const allPlayers = world.getAllPlayers();
        allPlayers.forEach(p => {
            if(p === sendTo){
                utils.runPlayerCommand(sender, `msg @a[name=${sendTo.name}] ${msg}`);
                main_menu(sender)
            }
        });
    }
}

async function displayMemoForm(player, memo) {
    // Set layout
    const MemoForm = new ActionFormData().title(memoData.name);
    
    MemoForm.body(
        `${gld.getScreenTitle(player)}` +
        // `§bMemo Title:§r ${memo.title}\n\n` +
        `${memo.text}\n\n\n\n`
    );

    MemoForm.button("§9Edit Memo", "textures/goe/spa/ui/notes");    
    MemoForm.button("§3Send Memo", "textures/goe/spa/ui/notes");    
    MemoForm.button("§4Delete Memo", "textures/goe/spa/ui/delete");    
    MemoForm.button("Back", "textures/goe/spa/ui/back");  

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

        player.playSound("goe_spa:button_click");
        if (result.selection === 0) {
            await showEditMemoForm(player, memo);
        } else if (result.selection === 1) {
            await showSendMemoForm(player, memo);
        } else if (result.selection === 2) {
            showConfirmForm(player, memo).then(async result => {
                inventory_utils.replacePhoneIfUIClosed(player, result);
                if (result.canceled) {
                    showApp(player);
                    return;
                }

                if (result.selection === 0) {
                    player.playSound("goe_spa:delete");
                    await deleteMemo(player, memo.title);
                } else {
                    player.playSound("goe_spa:reject");
                }

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

async function showConfirmForm(player, memo) {
    // Set layout
    const ConfirmForm = new ActionFormData();
    ConfirmForm.title(memoData.name);
    ConfirmForm.body(
        `The following memo ${memo.title} will be deleted!\n\n`
    );

    ConfirmForm.button("§aConfirm", "textures/goe/spa/ui/confirm");
    ConfirmForm.button("§4Cancel", "textures/goe/spa/ui/cancel");

    // Return promise
    return ConfirmForm.show(player);
}

async function getMemos(player) {
    const memos = [];
    for (let i = MAX_MEMOS - 1; i >= 0; i--) {
        const memoTitle = player.getDynamicProperty(`goe_spa_memo_${i}_title`);
        if (memoTitle === undefined)
            continue;

        const text = player.getDynamicProperty(`goe_spa_memo_${i}_text`);
        memos.push({ index: i, title: memoTitle, text: text, icon: "" });
    }

    return memos;
}

async function newMemo(player, title, text) {
    for (let i = 0; i < MAX_MEMOS; i++) {
        const memoTitle = player.getDynamicProperty(`goe_spa_memo_${i}_title`);
        if (memoTitle !== undefined)
            continue;

        player.setDynamicProperty(`goe_spa_memo_${i}_title`, title);
        player.setDynamicProperty(`goe_spa_memo_${i}_text`, text);
        break;
    }
}

async function deleteMemo(player, title) {
    for (let i = 0; i < MAX_MEMOS; i++) {
        const memoTitle = player.getDynamicProperty(`goe_spa_memo_${i}_title`);
        if (memoTitle === undefined || memoTitle !== title)
            continue;

        player.setDynamicProperty(`goe_spa_memo_${i}_title`, undefined);
        player.setDynamicProperty(`goe_spa_memo_${i}_text`, undefined);
        break;
    }
}

async function editMemo(player, oldTitle, newTitle, newText) {
    for (let i = 0; i < MAX_MEMOS; i++) {
        const memoTitle = player.getDynamicProperty(`goe_spa_memo_${i}_title`);
        if (memoTitle === undefined || memoTitle !== oldTitle)
            continue;

        player.setDynamicProperty(`goe_spa_memo_${i}_title`, newTitle);
        player.setDynamicProperty(`goe_spa_memo_${i}_text`, newText);
        break;
    }
}