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

/** List of Schedulebank data loaded from server
 * @type {ScheduleBank[]}
 */
window.schedulebankdata = [];
/**
 * Currently selected schedulebank row in the table
 * @type {JQuery<HTMLElement>|null}
 */
window.selectedschedulerow = null;

/**
 * Fill schedulebank table body with values
 * @param {ScheduleBank[]} vv values to fill
 */
function fill_schedulebanktablebody(vv) {
    $('#schedulebanktablebody').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.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);
        });
    });
    $('#tablesize').text("Table Size: " + vv.length);
}

/**
 * Reload timer bank from server
 * @param {string} APIURL API URL endpoint, default "ScheduleBank/"
 */
function reloadTimerBank(APIURL = "ScheduleBank/") {
    window.schedulebankdata = [];
    fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
        if (Array.isArray(okdata)) {
            window.schedulebankdata.push(...okdata);
            selectedschedulerow = null;
            fill_schedulebanktablebody(window.schedulebankdata);
        }
    }, (errdata) => {
        alert("Error loading schedulebank : " + errdata.message);
    });
}

$(document).ready(function () {
    console.log("schedulebank.js loaded successfully");
    $('#schedulebanktablebody').empty();
    selectedschedulerow = null;
    let $btnClear = $('#btnClear');
    let $btnAdd = $('#btnAdd');
    let $btnEdit = $('#btnEdit');
    let $btnRemove = $('#btnRemove');
    let $btnExport = $('#btnExport');
    let $btnImport = $('#btnImport');
    $btnEdit.prop('disabled', true);
    $btnRemove.prop('disabled', true);
    let APIURL = "ScheduleBank/";

    let $schedulemodal = $('#schedulemodal');
    // text input
    let $scheduleid = $schedulemodal.find('#scheduleid');
    // text input
    let $scheduledescription = $schedulemodal.find('#scheduledescription');
    // number input 0-23
    let $schedulehour = $schedulemodal.find('#schedulehour');
    // number input 0-59
    let $scheduleminute = $schedulemodal.find('#scheduleminute');

    //TODO ganti dropdown with list of messages from MessageBank
    // text input
    let $schedulesoundpath = $schedulemodal.find('#schedulesoundpath');
    // number input 0-5
    let $schedulerepeat = $schedulemodal.find('#schedulerepeat');
    // checkbox
    let $scheduleenable = $schedulemodal.find('#scheduleenable');
    // div for list of checkboxes
    let $schedulezones = $schedulemodal.find('#schedulezones');
    // radio button for everyday
    let $scheduleeveryday = $schedulemodal.find('#scheduleeveryday');
    // radio button for weekdays
    let $schedulesunday = $schedulemodal.find('#schedulesunday');
    let $schedulemonday = $schedulemodal.find('#schedulemonday');
    let $scheduletuesday = $schedulemodal.find('#scheduletuesday');
    let $schedulewednesday = $schedulemodal.find('#schedulewednesday');
    let $schedulethursday = $schedulemodal.find('#schedulethursday');
    let $schedulefriday = $schedulemodal.find('#schedulefriday');
    let $schedulesaturday = $schedulemodal.find('#schedulesaturday');
    // radio button for specific date
    let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
    // date input
    let $scheduledate = $schedulemodal.find('#scheduledate');

    $schedulespecialdate.on('change', function () {
        if ($(this).is(':checked')) {
            $scheduledate.prop('disabled', false);
        } else {
            $scheduledate.prop('disabled', true);
        }
    });

    function clearScheduleModal() {
        $scheduleid.prop('disabled', true).val('');
        $scheduledescription.val('');
        $schedulehour.val('0');
        $scheduleminute.val('0');
        $schedulesoundpath.val('');
        $schedulerepeat.val('0');
        $scheduleenable.prop('checked', true);
        $scheduleeveryday.prop('checked', false);
        $schedulesunday.prop('checked', false);
        $schedulemonday.prop('checked', false);
        $scheduletuesday.prop('checked', false);
        $schedulewednesday.prop('checked', false);
        $schedulethursday.prop('checked', false);
        $schedulefriday.prop('checked', false);
        $schedulesaturday.prop('checked', false);
        $schedulespecialdate.prop('checked', false);
        $scheduledate.prop('disabled', true).val('');


    }

    let $findschedule = $('#findschedule');
    $findschedule.on('input', function () {
        let searchTerm = $findschedule.val().toLowerCase();
        if (searchTerm.length > 0) {
            window.selectedschedulerow = null;
            let filtered = window.schedulebankdata.filter(item =>
                item.description.toLowerCase().includes(searchTerm)
                || item.soundpath.toLowerCase().includes(searchTerm)
                || item.broadcastZones.toLowerCase().includes(searchTerm));
            fill_schedulebanktablebody(filtered);
        } else {
            window.selectedschedulerow = null;
            fill_schedulebanktablebody(window.schedulebankdata);
        }
    });


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

    });
    $btnAdd.click(() => {
        $schedulemodal.modal('show');
        clearScheduleModal();

        $schedulemodal.off('click.scheduleclose').on('click.scheduleclose', '#scheduleclose', function () {
            $schedulemodal.modal('hide');
        });
        $schedulemodal.off('click.schedulesave').on('click.schedulesave', '#schedulesave', function () {
            // Gather form values
            const Description = $scheduledescription.val();
            const Soundpath = $schedulesoundpath.val();
            const Repeat = parseInt($schedulerepeat.val(), 10);
            const Enable = $scheduleenable.is(':checked');
            // Collect selected days
            let Day = "";
            if ($scheduleeveryday.is(':checked')) {
                Day = "Everyday";
            } else if ($schedulespecialdate.is(':checked')) {
                Day = $scheduledate.val();
            } else {

                if ($schedulesunday.is(':checked')) Day = "Sunday";
                if ($schedulemonday.is(':checked')) Day = "Monday";
                if ($scheduletuesday.is(':checked')) Day = "Tuesday";
                if ($schedulewednesday.is(':checked')) Day = "Wednesday";
                if ($schedulethursday.is(':checked')) Day = "Thursday";
                if ($schedulefriday.is(':checked')) Day = "Friday";
                if ($schedulesaturday.is(':checked')) Day = "Saturday";
            }
            // Broadcast zones (assuming comma-separated string)
            const BroadcastZones = $schedulezones.val();

            // Validate required fields
            if (!Description || !Soundpath || Day === "") {
                alert("Description, sound path, and day are required.");
                return;
            }

            // Format time as HH:mm
            const hour = parseInt($schedulehour.val(), 10);
            const minute = parseInt($scheduleminute.val(), 10);
            const Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;

            // Prepare object
            const scheduleObj = {
                Description,
                Day,
                Time,
                Soundpath,
                Repeat,
                Enable,
                BroadcastZones
            };

            fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => {
                alert("Success add schedule: " + okdata.message);
                reloadTimerBank(APIURL);
            }, (errdata) => {
                alert("Error add schedule: " + errdata.message);
            });

            $schedulemodal.modal('hide');
        });
    });
    $btnRemove.click(() => {
        if (window.selectedschedulerow) {
            let cells = window.selectedschedulerow.find('td');
            /** @type {ScheduleBank} */
            let sr = {
                index: Number(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}?`)) {
                fetchAPI(APIURL + "DeleteByIndex/" + sr.index, "DELETE", {}, null, (okdata) => {
                    reloadTimerBank(APIURL);
                    alert("Success delete schedule : " + okdata.message);
                }, (errdata) => {
                    alert("Error delete schedule : " + errdata.message);
                });
            }
        }
    });
    $btnEdit.click(() => {
        if (window.selectedschedulerow) {
            let cells = window.selectedschedulerow.find('td');
            /** @type {ScheduleBank} */
            let sr = {
                index: Number(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}?`)) {
                $schedulemodal.modal('show');
                // fill the form with existing data
                $scheduleid.val(sr.index);
                $scheduledescription.val(sr.description);
                let [hour, minute] = sr.time.split(':').map(num => parseInt(num, 10));
                $schedulehour.val(hour.toString());
                $scheduleminute.val(minute.toString());
                $schedulesoundpath.val(sr.soundpath);
                $schedulerepeat.val(sr.repeat.toString());
                $scheduleenable.prop('checked', sr.enable.toLowerCase() === 'true');
                switch (sr.day) {
                    case 'Everyday':
                        $scheduleeveryday.click();
                        break;
                    case 'Sunday':
                        $schedulesunday.click();
                        break;
                    case 'Monday':
                        $schedulemonday.click();
                        break;
                    case 'Tuesday':
                        $scheduletuesday.click();
                        break;
                    case 'Wednesday':
                        $schedulewednesday.click();
                        break;
                    case 'Thursday':
                        $schedulethursday.click();
                        break;
                    case 'Friday':
                        $schedulefriday.click();
                        break;
                    case 'Saturday':
                        $schedulesaturday.click();
                        break;
                    default:
                        // check if the day is in format dd/mm/yyyy
                        // and set the special date radio button and date input
                        if (/^\d{2}\/\d{2}\/\d{4}$/.test(sr.day)) {
                            $schedulespecialdate.click();
                            $scheduledate.val(sr.day);
                        }
                }

                $schedulemodal.off('click.scheduleclose').on('click.scheduleclose', '#scheduleclose', function () {
                    $schedulemodal.modal('hide');
                });
                $schedulemodal.off('click.schedulesave').on('click.schedulesave', '#schedulesave', function () {
                    // Gather form values
                    const Description = $scheduledescription.val();
                    const Soundpath = $schedulesoundpath.val();
                    const Repeat = parseInt($schedulerepeat.val(), 10);
                    const Enable = $scheduleenable.is(':checked');
                    // Collect selected days
                    let Day = "";
                    if ($scheduleeveryday.is(':checked')) {
                        Day = "Everyday";
                    } else if ($schedulespecialdate.is(':checked')) {
                        Day = $scheduledate.val();
                    } else {
                        if ($schedulesunday.is(':checked')) Day = "Sunday";
                        if ($schedulemonday.is(':checked')) Day = "Monday";
                        if ($scheduletuesday.is(':checked')) Day = "Tuesday";
                        if ($schedulewednesday.is(':checked')) Day = "Wednesday";
                        if ($schedulethursday.is(':checked')) Day = "Thursday";
                        if ($schedulefriday.is(':checked')) Day = "Friday";
                        if ($schedulesaturday.is(':checked')) Day = "Saturday";
                    }
                    // Broadcast zones (assuming comma-separated string)
                    const BroadcastZones = $schedulezones.val();

                    // Validate required fields
                    if (!Description || !Soundpath || Day === "") {
                        alert("Description, sound path, and day are required.");
                        return;
                    }

                    // Format time as HH:mm
                    const hour = parseInt($schedulehour.val(), 10);
                    const minute = parseInt($scheduleminute.val(), 10);
                    const Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;

                    // Prepare object
                    const scheduleObj = {
                        Description,
                        Day,
                        Time,
                        Soundpath,
                        Repeat,
                        Enable,
                        BroadcastZones
                    };

                    fetchAPI(APIURL + "UpdateByIndex/" + sr.index, "PATCH", {}, scheduleObj, (okdata) => {
                        alert("Success edit schedule: " + okdata.message);
                        reloadTimerBank(APIURL);
                    }, (errdata) => {
                        alert("Error edit schedule: " + errdata.message);
                    });

                    $schedulemodal.modal('hide');
                });
            }
        }
    });
    $btnExport.click(() => {
        DoExport(APIURL, "schedulebank.xlsx", {});
    });
    $btnImport.click(() => {
        DoImport(APIURL, (okdata) => {
            reloadTimerBank(APIURL);
            alert("Success import schedulebank from XLSX : " + okdata.message);
        }, (errdata) => {
            alert("Error importing schedulebank from XLSX : " + errdata.message);
        });
    });
});