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

/**
 * @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
 */

/**
 * @typedef {Object} LanguageBank
 * @property {number} index
 * @property {string} tag
 * @property {string} language
 * @
 */

/**
 * @typedef {Object} ScheduleBank
 * @property {number} index
 * @property {string} description
 * @property {string} day
 * @property {string} time
 * @property {string} soundpath
 * @property {number} repeat
 * @property {boolean} enable
 * @property {string} broadcastZones
 * @property {string} language
 */

/**
 * @typedef {Object} Log
 * @property {number} index
 * @property {string} datenya
 * @property {string} timenya
 * @property {string} machine
 * @property {string} description
 */

$(document).ready(function () {
    document.title = "Automatic Announcement System"
    $('#onlineindicator').attr('src', '/assets/img/red_circle.png');

    let soundbankdata = [];
    let selectedsoundrow = null;
    let messagebankdata = [];
    let selectedmessagerow = null;
    let languagebankdata = [];
    let selectedlanguagerow = null;
    let schedulebankdata = [];
    let selectedschedulerow = null;
    let logdata = [];

    /**
     * Fill soundbank table body with values
     * @param {SoundBank[]} vv values to fill
    */
    function fill_soundbanktablebody(vv) {
        $('#soundbanktablebody').empty();
        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 (selectedsoundrow) {
                    selectedsoundrow.find('td').css('background-color', '');
                    if (selectedsoundrow.is($(this))) {
                        selectedsoundrow = null;
                        $('#btnRemove').prop('disabled', true);
                        $('#btnEdit').prop('disabled', true);
                        return;
                    }
                }
                $(this).find('td').css('background-color', '#ffeeba');
                selectedsoundrow = $(this);
                $('#btnRemove').prop('disabled', false);
                $('#btnEdit').prop('disabled', false);
            });
        });
        $('#tablesize').text("Table Size: " + vv.length);
    }

    /**
     * Fill messagebank table body with values
    * @param {MessageBank[]} vv values to fill
    */
    function fill_messagebanktablebody(vv) {
        $('#messagebanktablebody').empty();
        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 (selectedmessagerow) {
                    selectedmessagerow.find('td').css('background-color', '');
                    if (selectedmessagerow.is($(this))) {
                        selectedmessagerow = null;
                        $('#btnRemove').prop('disabled', true);
                        $('#btnEdit').prop('disabled', true);
                        return;
                    }
                }
                $addedrow.find('td').css('background-color', '#ffeeba');
                selectedmessagerow = $addedrow;
                $('#btnRemove').prop('disabled', false);
                $('#btnEdit').prop('disabled', false);
            });
        });
        console.log("loaded " + vv.length + " messagebank items");
    }

    /**
     * Fill languagebank table body with values
     * @param {LanguageBank[]} vv values to fill
     */
    function fill_languagebanktablebody(vv) {
        $('#languagebanktablebody').empty();
        vv.forEach(item => {
            const row = `<tr>
                                <td>${item.index}</td>
                                <td>${item.tag}</td>
                                <td>${item.language}</td>
                            </tr>`;
            $('#languagebanktablebody').append(row);
            let $addedrow = $('#languagebanktablebody tr:last');
            $addedrow.click(function () {
                if (selectedlanguagerow) {
                    selectedlanguagerow.find('td').css('background-color', '');
                    if (selectedlanguagerow.is($(this))) {
                        selectedlanguagerow = null;
                        $('#btnRemove').prop('disabled', true);
                        $('#btnEdit').prop('disabled', true);
                        return;
                    }
                }
                $addedrow.find('td').css('background-color', '#ffeeba');
                selectedlanguagerow = $addedrow;
                $('#btnRemove').prop('disabled', false);
                $('#btnEdit').prop('disabled', false);
            });
        });
        console.log("loaded " + vv.length + " languagebank items");
    }

    /**
     * Fill schedulebank table body with values
     * @param {ScheduleBank[]} vv values to fill
     */
    function fill_schedulebanktablebody(vv) {
        $('#schedulebanktablebody').empty();
        vv.forEach(item => {
            const row = `<tr>
                                <td>${item.index}</td>
                                <td>${item.description}</td>
                                <td>${item.day}</td>
                                <td>${item.time}</td>
                                <td>${item.soundpath}</td>
                                <td>${item.repeat}</td>
                                <td>${item.enable}</td>
                                <td>${item.broadcastZones}</td>
                                <td>${item.language}</td>
                            </tr>`;
            $('#schedulebanktablebody').append(row);
            let $addedrow = $('#schedulebanktablebody tr:last');
            $addedrow.click(function () {
                if (selectedschedulerow) {
                    selectedschedulerow.find('td').css('background-color', '');
                    if (selectedschedulerow.is($(this))) {
                        selectedschedulerow = null;
                        $('#btnRemove').prop('disabled', true);
                        $('#btnEdit').prop('disabled', true);
                        return;
                    }
                }
                $addedrow.find('td').css('background-color', '#ffeeba');
                selectedschedulerow = $addedrow;
                $('#btnRemove').prop('disabled', false);
                $('#btnEdit').prop('disabled', false);
            });
        });
        console.log("loaded " + vv.length + " schedulebank items");
    }

    /**
     * Fill log table body with values
     * @param {Log[]} vv values to fill
     */
    function fill_logtablebody(vv) {
        $('#logtablebody').empty();
        vv.forEach(item => {
            const row = `<tr>
                                <td>${item.index}</td>
                                <td>${item.datenya}</td>
                                <td>${item.timenya}</td>
                                <td>${item.machine}</td>
                                <td>${item.description}</td>
                            </tr>`;
            $('#logtablebody').append(row);
        });
        console.log("loaded " + vv.length + " log items");
    }


    const ws = new WebSocket(window.location.pathname + '/ws');


    ws.onopen = () => {
        console.log('WebSocket connection established');
        $('#onlineindicator').attr('src', '/assets/img/green_circle.png');
    };
    ws.onmessage = (event) => {
        let rep = JSON.parse(event.data);
        let cmd = rep.reply
        let data = rep.data;
        if (cmd && cmd.length > 0) {
            switch (cmd) {
                case "getCPUStatus":
                    $('#cpustatus').text("CPU Usage: " + data)
                    break;
                case "getMemoryStatus":
                    $('#ramstatus').text("Memory Usage: " + data)
                    break;
                case "getDiskStatus":
                    $('#diskstatus').text("Disk Usage: " + data)
                    break;
                case "getNetworkStatus":
                    $('#networkstatus').text("Network Usage: " + data)
                    break;
                case "getSystemTime":
                    $('#datetimetext').text(data)
                    break;
                case "getSoundBankList":
                    let $soundbankfilter = $('#findsoundbank');
                    $soundbankfilter.empty();
                    soundbankdata = [];
                    fill_soundbanktablebody(soundbankdata)
                    let xx = JSON.parse(data);
                    if (Array.isArray(xx) && xx.length > 0) {
                        soundbankdata = xx;
                        fill_soundbanktablebody(soundbankdata);
                        $soundbankfilter.prop('disabled', false);
                        $soundbankfilter.off('input').on('input', function () {
                            const filterText = $(this).val().toLowerCase();
                            if (filterText.length === 0) {
                                fill_soundbanktablebody(soundbankdata);
                                return;
                            } else {
                                const filtered = soundbankdata.filter(item =>
                                    item.description && item.description.toLowerCase().startsWith(filterText)
                                );
                                fill_soundbanktablebody(filtered);
                            }

                        });
                    } else {
                        $soundbankfilter.prop('disabled', true);
                        alert("No soundbank data available");
                    }
                    break;
                case "getMessageBankList":
                    messagebankdata = [];
                    fill_messagebanktablebody(messagebankdata);
                    let yy = JSON.parse(data);
                    if (Array.isArray(yy) && yy.length > 0) {
                        messagebankdata = yy;
                        fill_messagebanktablebody(messagebankdata);
                    } else alert("No messagebank data available");
                    break;
                case "getLanguageList":
                    languagebankdata = []
                    fill_languagebanktablebody(languagebankdata);
                    let zz = JSON.parse(data);
                    if (Array.isArray(zz) && zz.length > 0) {
                        languagebankdata = zz;
                        fill_languagebanktablebody(languagebankdata);
                    } else alert("No language data available");
                    break;
                case "getTimerList":
                    schedulebankdata = []
                    fill_schedulebanktablebody(schedulebankdata);
                    let aa = JSON.parse(data);
                    if (Array.isArray(aa) && aa.length > 0) {
                        schedulebankdata = aa;
                        fill_schedulebanktablebody(schedulebankdata);
                    } else alert("No schedule data available");
                    break;
                case "getLog":
                    let $logfilter = $('#searchfilter');
                    logdata = [];
                    fill_logtablebody(logdata);
                    let bb = JSON.parse(data);
                    if (Array.isArray(bb) && bb.length > 0) {
                        logdata = bb;
                        fill_logtablebody(logdata);
                    } else alert("No log data available");
                    break;
                case "getSetting":
                    console.log("Setting:");
                    console.log(data);
                    break;
                case "clearSoundBank":
                    soundbankdata = [];
                    selectedsoundrow = null;
                    fill_soundbanktablebody(soundbankdata);
                    alert(`Clear SoundBank Result : ${data}`);
                    break;
                case "clearMessageBank":
                    messagebankdata = [];
                    selectedmessagerow = null;
                    fill_messagebanktablebody(messagebankdata);
                    alert(`Clear MessageBank Result : ${data}`);
                    break;
                case "clearLanguageBank":
                    languagebankdata = [];
                    selectedlanguagerow = null;
                    fill_languagebanktablebody(languagebankdata);
                    alert(`Clear LanguageBank Result : ${data}`);
                    break;
                case "clearTimerBank":
                    schedulebankdata = [];
                    selectedschedulerow = null;
                    fill_schedulebanktablebody(schedulebankdata);
                    alert(`Clear ScheduleBank Result : ${data}`);
                    break;
            }
        }
    };
    ws.onclose = () => {
        console.log('WebSocket connection closed');
        $('#onlineindicator').attr('src', '/assets/img/red_circle.png');
    };
    // ws.onerror = (error) => {
    //     console.error('WebSocket error:', error);
    // };

    /**
     * Send a command to the WebSocket server.
     * @param {String} command command to send
     * @param {String} data data to send
     */
    function sendCommand(command, data) {
        if (ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify({ command, data }));
        } else {
            console.error('WebSocket is not open');
        }
    }

    setInterval(() => {
        sendCommand("getCPUStatus", "")
        sendCommand("getMemoryStatus", "")
        sendCommand("getDiskStatus", "")
        sendCommand("getNetworkStatus", "")
        sendCommand("getSystemTime", "")
    }, 1000)

    let sidemenu = new bootstrap.Offcanvas('#offcanvas-menu');
    $('#showmenu').click(() => { sidemenu.show(); })


    $('#soundbanklink').click(() => {
        sidemenu.hide();
        $('#content').load('soundbank.html', function (response, status, xhr) {
            if (status === "success") {
                console.log("Soundbank content loaded successfully");
                // initialize first state of buttons and text input
                $('#soundbanktablebody').empty();
                selectedsoundrow = null;
                const $btnRemove = $('#btnRemove');
                const $btnEdit = $('#btnEdit');
                const $modal = $('#soundbankmodal');
                const modalEl = $modal[0];
                const modal = bootstrap.Modal.getOrCreateInstance(modalEl); // creates or reuses
                $btnRemove.prop('disabled', true);
                $btnEdit.prop('disabled', true);





                sendCommand("getSoundBankList", "");
                $('#btnClear').click(() => {
                    if (confirm(`Are you sure want to clear Soundbank ? This procedure is not reversible`)) {
                        sendCommand("clearSoundBank", "");
                    }
                });
                $('#btnAdd').click(() => {
                    modal.show();
                    $modal.off('hidden.bs.modal').on('hidden.bs.modal', function () {
                        const desc = $('#description').val();
                        console.log('Description input value:', desc);
                        // You can use desc here (e.g., send to server)
                    });
                });
                $btnRemove.click(() => {
                    if (selectedsoundrow) {
                        let cells = selectedsoundrow.find('td');
                        /** @type {SoundBank} */
                        let sb = {
                            index: 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}?`)) {
                            sendCommand("deleteSoundBank", sb);
                        }
                    }
                });
                $btnEdit.click(() => {
                    if (selectedsoundrow) {
                        let cells = selectedsoundrow.find('td');
                        /** @type {SoundBank} */
                        let sb = {
                            index: 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.show();
                            $modal.off('hidden.bs.modal').on('hidden.bs.modal', function () {
                                const desc = $('#description').val();
                                console.log('Description input value:', desc);
                                // You can use desc here (e.g., send to server)
                            });
                        }
                    }
                });
                $('#btnExport').click(() => {
                    alert("Feature disabled for now");
                });
                $('#btnImport').click(() => {
                    alert("Feature disabled for now");
                });
            } else {
                console.error("Error loading soundbank content:", xhr.status, xhr.statusText);
            }
        });

    })
    $('#messagebanklink').click(() => {
        sidemenu.hide();
        $('#content').load('messagebank.html', function (response, status, xhr) {
            if (status === "success") {
                console.log("Messagebank content loaded successfully");
                // initialize first state of buttons and text input
                $('#messagebanktablebody').empty();
                selectedmessagerow = null;
                let $btnRemove = $('#btnRemove');
                let $btnEdit = $('#btnEdit');
                $btnRemove.prop('disabled', true);
                $btnEdit.prop('disabled', true);

                sendCommand("getMessageBankList", "");
                $('#btnClear').click(() => {
                    if (confirm(`Are you sure want to clear Messagebank ? This procedure is not reversible`)) {
                        sendCommand("clearMessageBank", "");
                    }
                });
                $('#btnAdd').click(() => {
                    //TODO form add messagebank
                });
                $btnRemove.click(() => {
                    if (selectedmessagerow) {
                        let cells = selectedmessagerow.find('td');
                        /** @type {MessageBank} */
                        let mb = {
                            index: 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} `)) {
                            sendCommand("deleteMessageBank", mb);
                        }
                    }
                });
                $btnEdit.click(() => {
                    if (selectedmessagerow) {
                        let cells = selectedmessagerow.find('td');
                        /** @type {MessageBank} */
                        let mb = {
                            index: 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} `)) {
                            //TODO send edit command
                        }
                    }
                });
                $('#btnExport').click(() => {
                    alert("Feature disabled for now");
                });
                $('#btnImport').click(() => {
                    alert("Feature disabled for now");
                });
            } else {
                console.error("Error loading messagebank content:", xhr.status, xhr.statusText);
            }
        });

    })
    $('#languagelink').click(() => {
        sidemenu.hide();
        $('#content').load('language.html', function (response, status, xhr) {
            if (status === "success") {
                console.log("Language content loaded successfully");
                // initialize first state of buttons and text input
                $('#languagebanktablebody').empty();
                selectedlanguagerow = null;
                let $btnRemove = $('#btnRemove');
                let $btnEdit = $('#btnEdit');
                $btnRemove.prop('disabled', true);
                $btnEdit.prop('disabled', true);

                sendCommand("getLanguageList", "");
                $('#btnClear').click(() => {
                    if (confirm(`Are you sure want to clear Languagebank ? This procedure is not reversible`)) {
                        sendCommand("clearLanguageBank", "");
                    }
                });
                $('#btnAdd').click(() => {
                    //TODO form add language
                });
                $btnRemove.click(() => {
                    if (selectedlanguagerow) {
                        let cells = selectedlanguagerow.find('td');
                        /** @type {Language} */
                        let ll = {
                            index: cells.eq(0).text(),
                            tag: cells.eq(1).text(),
                            language: cells.eq(2).text()
                        }
                        if (confirm(`Are you sure to delete language [${ll.index}] Tag=${ll.tag} Language=${ll.language}?`)) {
                            sendCommand("deleteLanguage", ll);
                        }
                    }
                });
                $btnEdit.click(() => {
                    if (selectedlanguagerow) {
                        let cells = selectedlanguagerow.find('td');
                        /** @type {Language} */
                        let ll = {
                            index: cells.eq(0).text(),
                            tag: cells.eq(1).text(),
                            language: cells.eq(2).text()
                        }
                        if (confirm(`Are you sure to edit language [${ll.index}] Tag=${ll.tag} Language=${ll.language}?`)) {
                            //TODO send edit command
                        }
                    }
                });
                $('#btnExport').click(() => {
                    alert("Feature disabled for now");
                });
                $('#btnImport').click(() => {
                    alert("Feature disabled for now");
                });
            } else {
                console.error("Error loading language content:", xhr.status, xhr.statusText);
            }
        });
    })
    $('#timerlink').click(() => {
        sidemenu.hide();
        $('#content').load('timer.html', function (response, status, xhr) {
            if (status === "success") {
                console.log("Timer content loaded successfully");
                // initialize first state of buttons and text input
                $('#schedulebanktablebody').empty();
                selectedschedulerow = null;
                let $btnEdit = $('#btnEdit');
                let $btnRemove = $('#btnRemove');
                $btnEdit.prop('disabled', true);
                $btnRemove.prop('disabled', true);

                sendCommand("getTimerList", "");
                $('#btnClear').click(() => {
                    if (confirm(`Are you sure want to clear Timerbank ? This procedure is not reversible`)) {
                        sendCommand("clearTimerBank", "");
                    }
                });
                $('#btnAdd').click(() => {
                    //TODO form add timer
                });
                $btnRemove.click(() => {
                    if (selectedtimerow) {
                        let cells = selectedtimerow.find('td');
                        /** @type {ScheduleBank} */
                        let sr = {
                            index: cells.eq(0).text(),
                            description: cells.eq(1).text(),
                            day: cells.eq(2).text(),
                            time: cells.eq(3).text(),
                            soundpath: cells.eq(4).text(),
                            repeat: cells.eq(5).text(),
                            enable: cells.eq(6).text(),
                            broadcastZones: cells.eq(7).text(),
                            language: cells.eq(8).text()
                        }
                        if (confirm(`Are you sure to delete schedule [${sr.index}] Description=${sr.description}?`)) {
                            sendCommand("deleteSchedule", sr);
                        }
                    }
                });
                $btnEdit.click(() => {
                    if (selectedtimerow) {
                        let cells = selectedtimerow.find('td');
                        /** @type {ScheduleBank} */
                        let sr = {
                            index: cells.eq(0).text(),
                            description: cells.eq(1).text(),
                            day: cells.eq(2).text(),
                            time: cells.eq(3).text(),
                            soundpath: cells.eq(4).text(),
                            repeat: cells.eq(5).text(),
                            enable: cells.eq(6).text(),
                            broadcastZones: cells.eq(7).text(),
                            language: cells.eq(8).text()
                        }
                        if (confirm(`Are you sure to edit schedule [${sr.index}] Description=${sr.description}?`)) {
                            //TODO send edit command
                        }
                    }
                });
                $('#btnExport').click(() => {
                    alert("Feature disabled for now");
                });
                $('#btnImport').click(() => {
                    alert("Feature disabled for now");
                });
            } else {
                console.error("Error loading timer content:", xhr.status, xhr.statusText);
            }
        });
    })
    $('#loglink').click(() => {
        sidemenu.hide();
        $('#content').load('log.html', function (response, status, xhr) {
            if (status === "success") {
                console.log("Log content loaded successfully");
                const $logdate = $('#logdate');
                const $searchfilter = $('#searchfilter');
                if (!$logdate.val()) {
                    const today = new Date();
                    const dd = String(today.getDate()).padStart(2, '0');
                    const mm = String(today.getMonth() + 1).padStart(2, '0');
                    const yyyy = today.getFullYear();
                    $logdate.val(`${yyyy}-${mm}-${dd}`);
                }
                $logdate.off('change').on('change', function () {
                    const selected = $(this).val();
                    if (selected) {
                        const [year, month, day] = selected.split('-');
                        const formatted = `${day}/${month}/${year}`;
                        sendCommand("getLog", logRequstData(formatted, $searchfilter.val()));
                    }
                });
                const selected = $logdate.val();
                if (selected) {
                    const [year, month, day] = selected.split('-');
                    const formatted = `${day}/${month}/${year}`;
                    sendCommand("getLog", logRequstData(formatted, $searchfilter.val()));
                }
            } else {
                console.error("Error loading log content:", xhr.status, xhr.statusText);
            }
        });

    })
    $('#settinglink').click(() => {
        sidemenu.hide();
        $('#content').load('setting.html', function (response, status, xhr) {
            if (status === "success") {
                console.log("Setting content loaded successfully");
                sendCommand("getSetting", "");
            } else {
                console.error("Error loading setting content:", xhr.status, xhr.statusText);
            }
        });
    })
    $('#logoutlink').click(() => {
        window.location.href = "login.html"
    })


    /**
     * Create log Request Data
     * @param {String} logdate in format dd/mm/yyyy
     * @param {String} logfilter 
     * @returns JSON string of log Request data
     */
    function logRequstData(logdate, logfilter) {
        if (logdate && logdate.length > 0) {
            const dateRegex = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
            if (dateRegex.test(logdate)) {
                // logdate is valid
                return JSON.stringify({
                    date: logdate,
                    filter: logfilter
                })
            }

        }
        return ""
    }
});