/**
 * @typedef {Object} MessageBank
 * @property {number} index
 * @property {string} description
 * @property {string} language
 * @property {number} aNN_ID
 * @property {string} voice_Type
 * @property {string} message_Detail
 * @property {string} message_TAGS
 */

/**
 * List of Messagebank data loaded from server
 * @type {MessageBank[]}
 */
window.messagebankdata ??= [];
/**
 * Currently selected messagebank row in the table
 * @type {JQuery<HTMLElement>|null}
 */
window.selectedmessagerow = null;

/**
 * Fill messagebank table body with values
* @param {MessageBank[]} vv values to fill
*/
function fill_messagebanktablebody(vv) {
    $('#messagebanktablebody').empty();
    if (!Array.isArray(vv) || vv.length === 0) return;
    vv.forEach(item => {
        const row = `<tr>
                     <td>${item.index}</td>
                     <td>${item.description}</td>
                     <td>${item.language}</td>
                     <td>${item.aNN_ID}</td>
                     <td>${item.voice_Type}</td>
                     <td>${item.message_Detail}</td>
                     <td>${item.message_TAGS}</td>
                            </tr>`;
        $('#messagebanktablebody').append(row);
        let $addedrow = $('#messagebanktablebody tr:last');
        $addedrow.click(function () {
            if (window.selectedmessagerow) {
                window.selectedmessagerow.find('td').css('background-color', '');
                if (window.selectedmessagerow.is($(this))) {
                    window.selectedmessagerow = null;
                    $('#btnRemove').prop('disabled', true);
                    $('#btnEdit').prop('disabled', true);
                    return;
                }
            }
            $addedrow.find('td').css('background-color', '#ffeeba');
            window.selectedmessagerow = $addedrow;
            $('#btnRemove').prop('disabled', false);
            $('#btnEdit').prop('disabled', false);
        });
    });

    $('#tablesize').text("Table Size: " + vv.length);
}

/**
* Reload message bank from server
* @param {string} APIURL API URL endpoint, default "MessageBank/"
*/
function reloadMessageBank(APIURL = "MessageBank/") {
    window.messagebankdata ??= [];
    fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
        if (Array.isArray(okdata)) {
            window.messagebankdata.push(...okdata);
            window.selectedmessagerow = null;
            fill_messagebanktablebody(window.messagebankdata);
        }
    }, (errdata) => {
        alert("Error loading messagebank : " + errdata.message);
    });
}

$(document).ready(function () {
    console.log("messagebank.js loaded");
    $('#messagebanktablebody').empty();
    window.selectedmessagerow = null;
    let $btnClear = $('#btnClear');
    let $btnAdd = $('#btnAdd');
    let $btnRemove = $('#btnRemove');
    let $btnEdit = $('#btnEdit');
    let $btnExport = $('#btnExport');
    let $btnImport = $('#btnImport');
    $btnRemove.prop('disabled', true);
    $btnEdit.prop('disabled', true);
    let APIURL = "MessageBank/";
    let $findmessage = $('#findmessage');

    // modal for add / edit messagebank
    let $modal = $('#messagebankmodal');
    // text input, disabled by default
    let $messageindex = $modal.find('#messageindex');
    // text input
    let $messagedescription = $modal.find('#messagedescription');
    // select input, options loaded from languages[]
    let $messagelanguage = $modal.find('#messagelanguage');
    // number input from 1 to 100
    let $messageannid = $modal.find('#messageannid');
    // select input, options loaded from voiceTypes[]
    let $messagevoicetype = $modal.find('#messagevoicetype');
    // list <ul> of available categories and phrases
    let $messageavailablevariables = $modal.find('#messageavailablevariables');
    // list <ul> of selected categories and phrases
    let $messageselectedvariables = $modal.find('#messageselectedvariables');
    // for clearing messageselectedvariables
    let $btnclearlist = $modal.find('#btnclearlist');
    // for removing selected item from messageselectedvariables
    let $btnremovefromlist = $modal.find('#btnremovefromlist');
    // for adding selected item from messageavailablevariables to messageselectedvariables
    let $btnaddtolist = $modal.find('#btnaddtolist');

    /**
     * Refill messageavailablevariables options from categories[] 
     * and soundbankdata with category "Phrase" if messagelanguage and messagevoicetype are selected
     */
    function refill_messageavailablevariables() {
        $messageavailablevariables.empty();
        categories.forEach(cat => {
            $messageavailablevariables.append(ListItem(`[${cat}]`));
        });
        let lang = $messagelanguage.val();
        let vt = $messagevoicetype.val();
        if (lang && lang.length > 0){
            console.log("Selected Language:", lang);
            if (vt && vt.length > 0){
                console.log("Selected Voice Type:", vt);
                
                fetchAPI(`SoundBank/GetPhrases/${lang}/${vt}`, "GET", {}, null, (okdata) => {
                    if (Array.isArray(okdata) && okdata.length > 0) {
                        console.log(`Loaded ${okdata.length} phrases from soundbank for language=${lang} and voiceType=${vt}`);
                        console.log(JSON.stringify(okdata));
                        okdata.forEach(sb => {
                            if (sb.description && sb.description.length > 0) {
                                $messageavailablevariables.append(ListItem(`${sb.description} [${sb.TAG}]`));
                            }
                        });
                    }
                }, (errdata) => {
                    //alert("Error loading phrases from soundbank : " + errdata.message);
                });
            }
            
        }
        

    }

    /**
     * Clear message modal to default state
     */
    function clearMessageModal() {
        $messageindex.val('').prop('disabled', true);
        $messagedescription.val('');
        // fill messagelanguage options from languages[]
        $messagelanguage.empty();
        window.languages.forEach(lang => {
            $messagelanguage.append(new Option(lang, lang));
        });
        $messagelanguage.val(null);
        $messagelanguage.on('change', function () {
            refill_messageavailablevariables();
        });
        // set default annid to 1
        $messageannid.val(1);
        // fill messagevoicetype options from voiceTypes[]
        $messagevoicetype.empty();
        window.voiceTypes.forEach(vt => {
            $messagevoicetype.append(new Option(vt, vt));
        });
        $messagevoicetype.val(null);
        $messagevoicetype.on('change', function () {
            refill_messageavailablevariables();
        });

        refill_messageavailablevariables();
        $messageselectedvariables.empty();

        // event on btnclearlist
        $btnclearlist.off('click').on('click', function () {
            if ($messageselectedvariables.children().length > 0) {
                if (confirm("Are you sure want to clear selected variables list?")) {
                    $messageselectedvariables.empty();
                }
            }
        });

        // event on btnremovefromlist
        $btnremovefromlist.off('click').on('click', function () {
            let $selected = $messageselectedvariables.find('option:selected');
            if ($selected.length > 0) {
                $selected.remove();
            }

        });

        // event on btnaddtolist
        $btnaddtolist.off('click').on('click', function () {
            let $selected = $messageavailablevariables.find('option:selected');
            if ($selected.length > 0) {
                $selected.each(function () {
                    $messageselectedvariables.append($(this).clone());
                });
            }
        });
    }


    $findmessage.on('input', function () {
        let searchTerm = $findmessage.val().toLowerCase();
        if (searchTerm.length > 0) {
            window.selectedmessagerow = null;
            let filtered = window.messagebankdata.filter(item => item.description.toLowerCase().includes(searchTerm) || item.message_Detail.toLowerCase().includes(searchTerm) || item.message_TAGS.toLowerCase().includes(searchTerm));
            fill_messagebanktablebody(filtered);
        } else {
            window.selectedmessagerow = null;
            fill_messagebanktablebody(window.messagebankdata);
        }
    });


    reloadMessageBank(APIURL);
    $btnClear.click(() => {
        DoClear(APIURL, "Messagebank", (okdata) => {
            reloadMessageBank(APIURL);
            alert("Success clear messagebank : " + okdata.message);
        }, (errdata) => {
            alert("Error clear messagebank : " + errdata.message);
        });

    });
    $btnAdd.click(() => {

        $modal.modal('show');
        clearMessageModal();

        // event on Click save button
        $modal.off('click.messagebanksave').on('click.messagebanksave', '#messagebanksave', function () {
            let description = $messagedescription.val().trim();
            let language = $messagelanguage.val();
            let annid = parseInt($messageannid.val());
            let voicetype = $messagevoicetype.val();
            let messagedetail = "";
            let messagetags = "";

            // iterate messageselectedvariables children
            $messageselectedvariables.children().each(function () {
                let val = $(this).text().trim();
                if (val.length > 0) {
                    if (val.startsWith('[') && val.endsWith(']')) {
                        // categories
                        messagetags += (messagetags.length > 0 ? " " : "") + val;
                        messagedetail += (messagedetail.length > 0 ? " " : "") + val;
                    } else {
                        // phrases
                        // find in soundbankdata by description with specified language and voicetype
                        let sb = soundbankdata
                            .filter(sb => sb.language.toLowerCase() === language.toLowerCase())
                            .filter(sb => sb.voiceType.toLowerCase() === voicetype.toLowerCase())
                            .find(sb => sb.Description.toLowerCase() === val.toLowerCase());
                        if (sb) {
                            messagedetail += (messagedetail.length > 0 ? " " : "") + sb.Description;
                            messagetags += (messagetags.length > 0 ? " " : "") + sb.tag;
                        }
                    }
                }
            });

            if (description.length === 0) {
                alert("Description cannot be empty");
                return;
            }
            if (!language) {
                alert("Language cannot be empty");
                return;
            }
            if (isNaN(annid) || annid < 1 || annid > 100) {
                alert("ANN_ID must be a number between 1 and 100");
                return;
            }
            if (!voicetype) {
                alert("Voice Type cannot be empty");
                return;
            }
            if (messagedetail.length === 0 || messagetags.length === 0) {
                alert("Message haven't been constructed, please add categories and phrases");
                return;
            }


            let mb = {
                Description: description,
                Language: language,
                ANN_ID: annid,
                Voice_Type: voicetype,
                Message_Detail: messagedetail,
                Message_TAGS: messagetags
            };
            // send to server using fetchAPI
            fetchAPI(APIURL + "Add", "POST", mb, null, (okdata) => {
                reloadMessageBank(APIURL);
                alert("Success add new messagebank : " + okdata.message);
            }, (errdata) => {
                alert("Error add new messagebank : " + errdata.message);
            });

            $modal.modal('hide');
        });
        // event on Click close button
        $modal.off('click.messagebankclose').on('click.messagebankclose', '#messagebankclose', function () {
            $modal.modal('hide');
        });
    });
    $btnRemove.click(() => {
        if (window.selectedmessagerow) {
            let cells = window.selectedmessagerow.find('td');
            /** @type {MessageBank} */
            let mb = {
                index: Number(cells.eq(0).text()),
                description: cells.eq(1).text(),
                language: cells.eq(2).text(),
                aNN_ID: parseInt(cells.eq(3).text()),
                voice_Type: cells.eq(4).text(),
                message_Detail: cells.eq(5).text(),
                message_TAGS: cells.eq(6).text()
            }

            if (confirm(`Are you sure to delete messagebank [${mb.index}] Description=${mb.description}? ANN_ID=${mb.aNN_ID} Language=${mb.language} Voice_Type=${mb.voice_Type} `)) {
                fetchAPI(APIURL + "DeleteByIndex/" + mb.index, "DELETE", {}, null, (okdata) => {
                    reloadMessageBank(APIURL);
                    alert("Success delete messagebank : " + okdata.message);
                }, (errdata) => {
                    alert("Error delete messagebank : " + errdata.message);
                });
            }
        }
    });
    $btnEdit.click(() => {
        if (window.selectedmessagerow) {
            let cells = window.selectedmessagerow.find('td');
            /** @type {MessageBank} */
            let mb = {
                index: Number(cells.eq(0).text()),
                description: cells.eq(1).text(),
                language: cells.eq(2).text(),
                aNN_ID: parseInt(cells.eq(3).text()),
                voice_Type: cells.eq(4).text(),
                message_Detail: cells.eq(5).text(),
                message_TAGS: cells.eq(6).text()
            }
            if (confirm(`Are you sure to edit messagebank [${mb.index}] Description=${mb.description} ANN_ID=${mb.aNN_ID} Language=${mb.language} Voice_Type=${mb.voice_Type} `)) {
                $modal.modal('show');

                clearMessageModal();
                // Fill modal fields with selected messagebank data
                $messageindex.val(mb.index).prop('disabled', true);
                $messagedescription.val(mb.description);
                $messagelanguage.val(mb.language);
                $messagevoicetype.val(mb.voice_Type);
                $messageannid.val(mb.aNN_ID);
                // Refill message available variables
                refill_messageavailablevariables();
                // Fill messageselectedvariables from message_Detail and message_TAGS
                $messageselectedvariables.empty();
                if (mb.message_Detail) {
                    mb.message_Detail.split(' ').forEach(val => {
                        $messageselectedvariables.append(ListItem(val));
                    });
                }

                // Save button event
                $modal.off('click.messagebanksave').on('click.messagebanksave', '#messagebanksave', function () {
                    let description = $messagedescription.val().trim();
                    let language = $messagelanguage.val();
                    let annid = parseInt($messageannid.val());
                    let voicetype = $messagevoicetype.val();
                    let messagedetail = "";
                    let messagetags = "";
                    $messageselectedvariables.children().each(function () {
                        let val = $(this).text().trim();
                        if (val.length > 0) {
                            if (val.startsWith('[') && val.endsWith(']')) {
                                messagetags += (messagetags.length > 0 ? " " : "") + val;
                                messagedetail += (messagedetail.length > 0 ? " " : "") + val;
                            } else {
                                let sb = soundbankdata
                                    .filter(sb => sb.language.toLowerCase() === language.toLowerCase())
                                    .filter(sb => sb.voiceType.toLowerCase() === voicetype.toLowerCase())
                                    .find(sb => sb.Description && sb.Description.toLowerCase() === val.toLowerCase());
                                if (sb) {
                                    messagedetail += (messagedetail.length > 0 ? " " : "") + sb.Description;
                                    messagetags += (messagetags.length > 0 ? " " : "") + sb.tag;
                                }
                            }
                        }
                    });
                    if (description.length === 0) {
                        alert("Description cannot be empty");
                        return;
                    }
                    if (!language) {
                        alert("Language cannot be empty");
                        return;
                    }
                    if (isNaN(annid) || annid < 1 || annid > 100) {
                        alert("ANN_ID must be a number between 1 and 100");
                        return;
                    }
                    if (!voicetype) {
                        alert("Voice Type cannot be empty");
                        return;
                    }
                    if (messagedetail.length === 0 || messagetags.length === 0) {
                        alert("Message haven't been constructed, please add categories and phrases");
                        return;
                    }
                    let mbUpdate = {
                        Description: description,
                        Language: language,
                        ANN_ID: annid,
                        Voice_Type: voicetype,
                        Message_Detail: messagedetail,
                        Message_TAGS: messagetags
                    };
                    fetchAPI(APIURL + "UpdateByIndex/" + mb.index, "PATCH", mbUpdate, null, (okdata) => {
                        reloadMessageBank(APIURL);
                        alert("Success edit messagebank : " + okdata.message);
                    }, (errdata) => {
                        alert("Error edit messagebank : " + errdata.message);
                    });
                    $modal.modal('hide');
                });
                // Close button event
                $modal.off('click.messagebankclose').on('click.messagebankclose', '#messagebankclose', function () {
                    $modal.modal('hide');
                });

            }
        }
    });
    $btnExport.click(() => {
        DoExport(APIURL, "messagebank.xlsx", {});
    });
    $btnImport.click(() => {
        DoImport(APIURL, (okdata) => {
            reloadMessageBank(APIURL);
            alert("Success import messagebank : " + okdata.message);
        }, (errdata) => {
            alert("Error importing messagebank from XLSX : " + errdata.message);
        });
    });
});