

/**
 * @typedef {Object} Select2item
 * @property {number} id
 * @property {string} text
 */

/**
 * @typedef {Object} SoundBank
 * @property {number} index
 * @property {string} description
 * @property {string} tag
 * @property {string} category
 * @property {string} language
 * @property {string} voiceType
 * @property {string} path
 */

/**
 * List of Soundbank data loaded from server
 * @type {SoundBank[]}
 */
window.soundbankdata = [];
/**
 * Currently selected soundbank row in the table
 * @type {JQuery<HTMLElement>|null}
 */
window.selectedsoundrow = null;



/**
 * Select2 data source
 * See https://select2.org/data-sources/formats
 * @type {Select2item[]}
 */
window.select2data = [];

/**
 * Reload sound bank from server
 * @param {String} APIURL API URL endpoint, default "SoundBank/"
 */
function reloadSoundBank(APIURL = "SoundBank/") {
    window.soundbankdata = [];
    fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {

        if (Array.isArray(okdata)) {
            window.soundbankdata.push(...okdata);
            window.selectedsoundrow = null;
            fill_soundbanktablebody(window.soundbankdata);
        }
    }, (errdata) => {
        alert("Error loading soundbank : " + errdata.message);
    });
}

/**
     * Fill soundbank table body with values
     * @param {SoundBank[]} vv values to fill
    */
function fill_soundbanktablebody(vv) {
    $('#soundbanktablebody').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.tag}</td>
                     <td>${item.category}</td>
                     <td>${item.language}</td>
                     <td>${item.voiceType}</td>
                     <td>${item.path}</td>
                     </tr>`;
        $('#soundbanktablebody').append(row);
        let $addedrow = $('#soundbanktablebody tr:last');
        $addedrow.on('click', function () {
            if (window.selectedsoundrow) {
                window.selectedsoundrow.find('td').css('background-color', '');
                if (window.selectedsoundrow.is($(this))) {
                    window.selectedsoundrow = null;
                    $('#btnRemove').prop('disabled', true);
                    $('#btnEdit').prop('disabled', true);
                    return;
                }
            }
            $(this).find('td').css('background-color', '#ffeeba');
            window.selectedsoundrow = $(this);
            $('#btnRemove').prop('disabled', false);
            $('#btnEdit').prop('disabled', false);
        });
    });


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

/**
 * Reload soundbank files from server and filter by language, category, and voiceType
 * @param {String} language 
 * @param {String} category 
 * @param {String} voiceType 
 * @param {Function} cb callback function when done
 */
function reloadSoundbankFiles(language, category, voiceType, cb=null) {
    window.select2data = [];
    $('#modalpath').empty().trigger('change');
    if (language && language.length > 0) {
        if (category && category.length > 0) {
            if (voiceType && voiceType.length > 0) {
                fetchAPI(`ListFiles/${language}/${voiceType}/${category}`, "GET", {}, null, (okdata) => {
                    console.log("reloadSoundbankFiles: got " + okdata.length + " items");
                    if (Array.isArray(okdata)){
                        window.select2data = okdata.map(p => ({id: getFilenameFromPath(p), text: getFilenameFromPath(p)}));
                        
                        $('#modalpath').select2({
                            data: window.select2data,
                            placeholder: 'Select a sound file',
                            allowClear: true,
                            width: '100%',
                            dropdownParent: $('#soundbankmodal')
                        });
                        if (cb) cb();
                    }
                }, (errdata) => {
                    alert("Error loading soundbank files : " + errdata.message);
                });

            }
        }
    }

}

function getFilenameFromPath(path) {
    if (!path || path.length === 0) return "";
    if (path.includes('\\')) {
        let parts = path.split('\\');
        return parts[parts.length - 1];
    } else if (!path.includes('/')) {
        let parts = path.split('/');
        return parts[parts.length - 1];
    }
    
}




$(document).ready(function () {
    console.log("soundbank.js loaded successfully");
    $('#soundbanktablebody').empty();
    window.selectedsoundrow = 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 = "SoundBank/";
    let $modal = $('#soundbankmodal');
    let $modalindex = $modal.find('#modalindex');
    let $modaldescription = $modal.find('#modaldescription');
    let $modaltag = $modal.find('#modaltag');
    let $modalcategory = $modal.find('#modalcategory');
    let $modallanguage = $modal.find('#modallanguage');
    let $modalvoicetype = $modal.find('#modalvoicetype');
    let selected_category = null;
    let selected_language = null;
    let selected_voicetype = null;

    /**
     * Clear soundbank modal inputs
     */
    function clearSoundbankModal() {
        $modalindex.val('').prop('disabled', true);
        $modaldescription.val('');
        $modaltag.val('');
        // fill modalcategory options from categories[]
        $modalcategory.empty();
        categories.forEach(cat => {
            $modalcategory.append(new Option(cat, cat));
        });
        $modalcategory.val(null);
        // fill modallanguage options from languages[]
        $modallanguage.empty();
        languages.forEach(lang => {
            $modallanguage.append(new Option(lang, lang));
        });
        $modallanguage.val(null);
        // fill modalvoicetype options from voiceTypes[]
        $modalvoicetype.empty();
        voiceTypes.forEach(vt => {
            $modalvoicetype.append(new Option(vt, vt));
        });
        $modalvoicetype.val(null);
        $('#modalpath').select2()

    }

    reloadSoundBank(APIURL);
    $('#findsoundbank').on('input', function () {
        let searchTerm = $(this).val().trim().toLowerCase();
        if (searchTerm.length > 0) {
            window.selectedsoundrow = null;
            let filtered = window.soundbankdata.filter(item => item.description.toLowerCase().includes(searchTerm) || item.tag.toLowerCase().includes(searchTerm) || item.path.toLowerCase().includes(searchTerm));
            fill_soundbanktablebody(filtered);
        } else {
            window.selectedsoundrow = null;
            fill_soundbanktablebody(window.soundbankdata);
        }
    });
    $btnClear.click(() => {
        DoClear(APIURL, "Soundbank", (okdata) => {
            reloadSoundBank(APIURL);
            alert("Success clear soundbank : " + okdata.message);
        }, (errdata) => {
            alert("Error clear soundbank : " + errdata.message);
        });

    });

    function SetupEventForCategoryLanguageVoiceType() {
        $modalcategory.off('change').on('change', function () {
            selected_category = $(this).val();
            reloadSoundbankFiles(selected_language, selected_category, selected_voicetype);
        });
        $modallanguage.off('change').on('change', function () {
            selected_language = $(this).val();
            reloadSoundbankFiles(selected_language, selected_category, selected_voicetype);
        });
        $modalvoicetype.off('change').on('change', function () {
            selected_voicetype = $(this).val();
            reloadSoundbankFiles(selected_language, selected_category, selected_voicetype);
        });
    }

    $btnAdd.click(() => {

        $modal.modal('show');
        clearSoundbankModal();
        // event on selection change of language, category, voiceType
        SetupEventForCategoryLanguageVoiceType();


        // event on Click save button
        $modal.off('click.soundbanksave').on('click.soundbanksave', '#soundbanksave', function () {
            let description = $modaldescription.val().trim();
            let tag = $modaltag.val().trim();
            let category = $modalcategory.val();
            let language = $modallanguage.val();
            let voiceType = $modalvoicetype.val();
            let path = $('#soundbankmodal #modalpath').val();
            if (!description || description.length === 0) {
                alert("Description is required");
                return;
            }
            if (!tag || tag.length === 0) {
                alert("Tag is required");
                return;
            }
            if (!category || category.length === 0) {
                alert("Category is required");
                return;
            }
            if (!language || language.length === 0) {
                alert("Language is required");
                return;
            }
            if (!voiceType || voiceType.length === 0) {
                alert("Voice Type is required");
                return;
            }
            if (!path || path.length === 0) {
                alert("Path is required");
                return;
            }
            $modal.modal('hide');
            /**
             * @type {SoundBank}
             */
            let nsb = {
                index: 0,
                Description: description,
                TAG: tag,
                Category: category,
                Language: language,
                VoiceType: voiceType,
                Path: path
            }
            fetchAPI(APIURL + "Add", "POST", {}, nsb, (okdata) => {
                reloadSoundBank(APIURL);
                alert("Success add soundbank : " + okdata.message);
            }, (errdata) => {
                alert("Error add soundbank : " + errdata.message);
            });
        });
        // event on Click close button
        $modal.off('click.soundbankclose').on('click.soundbankclose', '#soundbankclose', function () {
            $modal.modal('hide');
        });
    });
    $btnRemove.click(() => {
        if (window.selectedsoundrow) {
            let cells = window.selectedsoundrow.find('td');
            /** @type {SoundBank} */
            let sb = {
                index: Number(cells.eq(0).text()),
                description: cells.eq(1).text(),
                tag: cells.eq(2).text(),
                category: cells.eq(3).text(),
                language: cells.eq(4).text(),
                voiceType: cells.eq(5).text(),
                path: cells.eq(6).text()
            }
            if (confirm(`Are you sure to delete soundbank [${sb.index}] Description=${sb.description} Tag=${sb.tag}?`)) {
                fetchAPI(APIURL + "DeleteByIndex/" + sb.index, "DELETE", {}, null, (okdata) => {
                    reloadSoundBank(APIURL);
                    alert("Success delete soundbank : " + okdata.message);
                }, (errdata) => {
                    alert("Error delete soundbank : " + errdata.message);
                });
            }
        }
    });
    $btnEdit.click(() => {
        if (window.selectedsoundrow) {
            let cells = window.selectedsoundrow.find('td');
            /** @type {SoundBank} */
            let sb = {
                index: Number(cells.eq(0).text()),
                Description: cells.eq(1).text(),
                TAG: cells.eq(2).text(),
                Category: cells.eq(3).text(),
                Language: cells.eq(4).text(),
                VoiceType: cells.eq(5).text(),
                Path: cells.eq(6).text()
            }
            if (confirm(`Are you sure to edit soundbank [${sb.index}] Description=${sb.Description} Tag=${sb.TAG}?`)) {
                $modal.modal('show');
                clearSoundbankModal();
                SetupEventForCategoryLanguageVoiceType();
                $modalindex.val(sb.index).prop('disabled', true);
                $modaldescription.val(sb.Description);
                $modaltag.val(sb.TAG);
                $modalcategory.val(sb.Category);
                selected_category = sb.Category;
                $modallanguage.val(sb.Language);
                selected_language = sb.Language;
                $modalvoicetype.val(sb.VoiceType);
                selected_voicetype = sb.VoiceType;
                // load soundbank files for selected language, category, voiceType
                reloadSoundbankFiles(selected_language, selected_category, selected_voicetype, () => {
                    // set selected path
                    $('#modalpath').val(getFilenameFromPath(sb.Path)).trigger('change');
                });


                
                // event on Click save button
                    $modal.off('click.soundbanksave').on('click.soundbanksave', '#soundbanksave', function () {
                        let description = $modaldescription.val().trim();
                        let tag = $modaltag.val().trim();
                        let category = $modalcategory.val();
                        let language = $modallanguage.val();
                        let voiceType = $modalvoicetype.val();
                        let path = $('#soundbankmodal #modalpath').val();
                        if (!description || description.length === 0) {
                            alert("Description is required");
                            return;
                        }
                        if (!tag || tag.length === 0) {
                            alert("Tag is required");
                            return;
                        }
                        if (!category || category.length === 0) {
                            alert("Category is required");
                            return;
                        }
                        if (!language || language.length === 0) {
                            alert("Language is required");
                            return;
                        }
                        if (!voiceType || voiceType.length === 0) {
                            alert("Voice Type is required");
                            return;
                        }
                        if (!path || path.length === 0) {
                            alert("Path is required");
                            return;
                        }
                        if (description === sb.Description && tag === sb.TAG && category === sb.Category && language === sb.Language && voiceType === sb.VoiceType && path === sb.Path) {
                            alert("No changes detected");
                            return;
                        }
                        sb.Description = description;
                        sb.TAG = tag;
                        sb.Category = category;
                        sb.Language = language;
                        sb.VoiceType = voiceType;
                        sb.Path = path;
                        fetchAPI(APIURL + "UpdateByIndex/" + sb.index, "PATCH", {}, sb, (okdata) => {
                            reloadSoundBank(APIURL);
                            alert("Success update soundbank : " + okdata.message);
                        }, (errdata) => {
                            alert("Error update soundbank : " + errdata.message);
                        });
                        $modal.modal('hide');

                    });
                    // event on Click close button
                    $modal.off('click.soundbankclose').on('click.soundbankclose', '#soundbankclose', function () {
                        $modal.modal('hide');
                    });
               
            }
        }
    });
    $btnExport.click(() => {
        DoExport(APIURL, "soundbank.xlsx", {});
    });
    $btnImport.click(() => {
        DoImport(APIURL, (okdata) => {
            reloadSoundBank(APIURL);
            alert("Success import soundbank : " + okdata.message);
        }, (errdata) => {
            alert("Error importing soundbank from XLSX : " + errdata.message);
        });
    });
});