/* modules/free/reminders/assets/js/admin.js */
(function (window, $) {
    'use strict';

    var modules = window.noesiaSwaAdminModules || (window.noesiaSwaAdminModules = {});
    var nsVars = window.noesia_admin_vars || {};
    var ajaxUrl = nsVars.ajax_url || '';
    var nonces = {
        request: nsVars.nonce || ''
    };
    var viewStorageKey = 'noesiaSwaRemindersViewMode';

    var state = {
        booted: false,
        bound: false,
        cache: [],
        loading: false,
        viewMode: 'classic',
        modalOpen: false,
        modalTimer: 0,
        lastModalTrigger: null
    };

    function escHtml(text) {
        return String(text == null ? '' : text)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

    function hasUi() {
        return $('#noesia-swa-reminders-items').length > 0 || $('.noesia-swa-icon-btn[data-noesia-swa-nav-target="reminders"]').length > 0;
    }

    function getRoot() {
        return $('#noesia-swa-reminders-app');
    }

    function getModal() {
        return $('#noesia-swa-reminders-modal');
    }

    function reminderStrings() {
        var s = (nsVars && nsVars.strings) ? nsVars.strings : {};

        return {
            loadError: String(s.reminders_load_error || 'Could not load reminders.'),
            saveError: String(s.reminders_save_error || 'Could not save reminder.'),
            toggleError: String(s.reminders_toggle_error || 'Could not update reminder.'),
            deleteError: String(s.reminders_delete_error || 'Could not delete reminder.'),
            validateError: String(s.reminders_validate_error || 'Add at least a Type or a Message before saving.'),
            created: String(s.reminders_created || 'Reminder created.'),
            updated: String(s.reminders_updated || 'Reminder updated.'),
            deleted: String(s.reminders_deleted || 'Reminder deleted.'),
            canceled: String(s.reminders_canceled || 'Editing canceled.'),
            noItems: String(s.reminders_empty || 'No reminders yet. Use Create Reminder to add your first reminder.'),
            noMatches: String(s.reminders_no_match || 'No reminder matches the current filters.'),
            visibleOne: String(s.reminders_visible_one || '1 reminder visible.'),
            visibleMany: String(s.reminders_visible_many || '%d reminders visible.'),
            noDueDate: String(s.reminders_no_due || 'No due date'),
            completed: String(s.reminders_completed || 'Completed'),
            overdue: String(s.reminders_overdue || 'Overdue'),
            today: String(s.reminders_today || 'Today'),
            open: String(s.reminders_open || 'Open'),
            due: String(s.reminders_due || 'Due:'),
            related: String(s.reminders_related || 'Related:'),
            untitled: String(s.reminders_untitled || 'Untitled reminder'),
            noFound: String(s.reminders_none_found || 'No reminders found'),
            noFoundSub: String(s.reminders_none_found_sub || 'Try changing the filters or create a new reminder.')
        };
    }

    function remindersSetMessage(text, isError) {
        var $msg = $('#noesia-swa-reminders-msg');

        if (!$msg.length) {
            return;
        }

        $msg
            .text(String(text || ''))
            .toggleClass('is-error', !!isError);
    }

    function reminderAjax(action, data) {
        return $.ajax({
            url: ajaxUrl,
            method: 'POST',
            dataType: 'json',
            data: $.extend({}, data || {}, {
                action: action,
                nonce: nonces.request
            })
        });
    }

    function reminderNormalizeItem(item) {
        if (!item || typeof item !== 'object') {
            return null;
        }

        return {
            id: String(item.id || ''),
            type: String(item.type || '').trim(),
            dueDate: String(item.dueDate || '').trim(),
            dueTime: String(item.dueTime || '').trim(),
            related: String(item.related || '').trim(),
            message: String(item.message || '').trim(),
            status: String(item.status || 'open') === 'completed' ? 'completed' : 'open',
            createdAt: parseInt(item.createdAt || 0, 10) || 0,
            updatedAt: parseInt(item.updatedAt || 0, 10) || 0,
            completedAt: parseInt(item.completedAt || 0, 10) || 0
        };
    }

    function reminderTodayYmd() {
        var now = new Date();
        var y = now.getFullYear();
        var m = String(now.getMonth() + 1).padStart(2, '0');
        var d = String(now.getDate()).padStart(2, '0');

        return y + '-' + m + '-' + d;
    }

    function reminderDueStamp(item) {
        var date = String((item && item.dueDate) || '').trim();
        var time = String((item && item.dueTime) || '').trim();
        var stamp;

        if (!date) {
            return 8640000000000000;
        }

        if (!time) {
            time = '23:59';
        }

        stamp = Date.parse(date + 'T' + time + ':00');
        return isNaN(stamp) ? 8640000000000000 : stamp;
    }

    function reminderFormatDue(item) {
        var t = reminderStrings();
        var date = String((item && item.dueDate) || '').trim();
        var time = String((item && item.dueTime) || '').trim();
        var label = date;
        var stamp;

        if (!date) {
            return t.noDueDate;
        }

        stamp = Date.parse(date + 'T12:00:00');

        if (!isNaN(stamp)) {
            label = new Date(stamp).toLocaleDateString([], {
                day: 'numeric',
                month: 'short',
                year: 'numeric'
            });
        }

        if (time) {
            label += ' · ' + time;
        }

        return label;
    }

    function reminderCollectFilters() {
        return {
            status: String($('#noesia-swa-reminders-filter-status').val() || 'open'),
            due: String($('#noesia-swa-reminders-filter-due').val() || 'all'),
            search: String($('#noesia-swa-reminders-search').val() || '').trim().toLowerCase()
        };
    }

    function reminderMatches(item, filters) {
        var text = (
            String(item.type || '') + ' ' +
            String(item.related || '') + ' ' +
            String(item.message || '')
        ).toLowerCase();
        var now;
        var today;
        var todayStamp;
        var endStamp;
        var dueStamp;
        var itemDate;

        if (filters.search && text.indexOf(filters.search) === -1) {
            return false;
        }

        if (filters.status !== 'all' && item.status !== filters.status) {
            return false;
        }

        if (filters.due === 'all') {
            return true;
        }

        if (item.status === 'completed') {
            return false;
        }

        now = Date.now();
        today = reminderTodayYmd();
        todayStamp = Date.parse(today + 'T00:00:00');
        endStamp = todayStamp + (7 * 24 * 60 * 60 * 1000);
        dueStamp = reminderDueStamp(item);
        itemDate = String(item.dueDate || '');

        if (filters.due === 'today') {
            return itemDate === today;
        }

        if (filters.due === 'overdue') {
            return !!itemDate && dueStamp < now && itemDate !== today;
        }

        if (filters.due === 'next7') {
            return !!itemDate && dueStamp >= todayStamp && dueStamp <= endStamp;
        }

        return true;
    }

    function computeReminderStats(items) {
        var now = Date.now();
        var today = reminderTodayYmd();
        var todayStamp = Date.parse(today + 'T00:00:00');
        var endStamp = todayStamp + (7 * 24 * 60 * 60 * 1000);
        var out = {
            overdue: 0,
            today: 0,
            upcoming: 0,
            completed: 0,
            openTotal: 0
        };

        (items || []).forEach(function (item) {
            var dueStamp = reminderDueStamp(item);
            var itemDate = String(item.dueDate || '');

            if (item.status === 'completed') {
                out.completed += 1;
                return;
            }

            out.openTotal += 1;

            if (itemDate === today) {
                out.today += 1;
            }

            if (itemDate && dueStamp < now && itemDate !== today) {
                out.overdue += 1;
            }

            if (itemDate && dueStamp >= todayStamp && dueStamp <= endStamp) {
                out.upcoming += 1;
            }
        });

        return out;
    }

    function syncReminderBadge(items) {
        var stats = computeReminderStats(items || []);
        var count = stats.openTotal;
        var shell = window.noesiaSwaAdminShell;
        var $btn = $('.noesia-swa-icon-btn[data-noesia-swa-nav-target="reminders"]').first();
        var $badge;

        if (shell && typeof shell.setActiveRemindersCount === 'function') {
            shell.setActiveRemindersCount(count, true);
        }

        if (!$btn.length) {
            return;
        }

        $badge = $btn.find('.noesia-swa-reminders-badge');

        if (!$badge.length) {
            $badge = $('<span class="noesia-swa-reminders-badge" hidden></span>');
            $btn.append($badge);
        }

        if (count > 0) {
            $badge.text(count > 99 ? '99+' : String(count)).removeAttr('hidden');
        } else {
            $badge.attr('hidden', true).text('');
        }
    }

    function reminderStatusBadge(item) {
        var t = reminderStrings();

        if (item.status === 'completed') {
            return '<span class="noesia-swa-rem-badge is-completed">' + escHtml(t.completed) + '</span>';
        }

        if (String(item.dueDate || '') && reminderMatches(item, { search: '', status: 'open', due: 'overdue' })) {
            return '<span class="noesia-swa-rem-badge is-overdue">' + escHtml(t.overdue) + '</span>';
        }

        if (String(item.dueDate || '') === reminderTodayYmd()) {
            return '<span class="noesia-swa-rem-badge is-today">' + escHtml(t.today) + '</span>';
        }

        return '<span class="noesia-swa-rem-badge is-open">' + escHtml(t.open) + '</span>';
    }

    function clearModalTimer() {
        if (state.modalTimer) {
            window.clearTimeout(state.modalTimer);
            state.modalTimer = 0;
        }
    }

    function openReminderModal(triggerEl) {
        var $modal = getModal();

        if (!$modal.length) {
            return false;
        }

        clearModalTimer();
        state.modalOpen = true;
        state.lastModalTrigger = triggerEl || document.activeElement || null;

        $modal.attr('hidden', false).removeAttr('hidden').attr('aria-hidden', 'false');
        $('body').addClass('noesia-swa-reminders-modal-open');

        window.requestAnimationFrame(function () {
            $modal.addClass('is-visible');
        });

        state.modalTimer = window.setTimeout(function () {
            $('#noesia-swa-rem-type').trigger('focus');
            state.modalTimer = 0;
        }, 60);

        return true;
    }

    function closeReminderModal() {
        var $modal = getModal();

        if (!$modal.length) {
            return false;
        }

        clearModalTimer();
        state.modalOpen = false;
        $modal.removeClass('is-visible').attr('aria-hidden', 'true');
        $('body').removeClass('noesia-swa-reminders-modal-open');

        state.modalTimer = window.setTimeout(function () {
            $modal.attr('hidden', true);
            if (state.lastModalTrigger && typeof state.lastModalTrigger.focus === 'function') {
                try {
                    state.lastModalTrigger.focus();
                } catch (err) {
                }
            }
            state.modalTimer = 0;
        }, 190);

        return true;
    }

    function loadViewMode() {
        var stored = '';

        try {
            stored = String(window.localStorage.getItem(viewStorageKey) || 'classic');
        } catch (err) {
            stored = 'classic';
        }

        state.viewMode = stored === 'grid' ? 'grid' : 'classic';
        return state.viewMode;
    }

    function applyViewMode(mode) {
        var normalized = mode === 'grid' ? 'grid' : 'classic';
        var $root = getRoot();
        var $toggle = $('#noesia-swa-reminders-view-mode');

        state.viewMode = normalized;

        if ($root.length) {
            $root.toggleClass('is-grid-view', normalized === 'grid');
            $root.attr('data-noesia-swa-reminders-view', normalized);
        }

        if ($toggle.length) {
            $toggle.prop('checked', normalized === 'grid');
        }

        try {
            window.localStorage.setItem(viewStorageKey, normalized);
        } catch (err) {
            return false;
        }

        return true;
    }

    function resetReminderForm() {
        $('#noesia-swa-rem-id').val('');
        $('#noesia-swa-rem-type').val('');
        $('#noesia-swa-rem-due-date').val(reminderTodayYmd());
        $('#noesia-swa-rem-due-time').val('');
        $('#noesia-swa-rem-related').val('');
        $('#noesia-swa-rem-message').val('');
        $('#noesia-swa-rem-delete').attr('hidden', true);
    }

    function fillReminderForm(id) {
        var found = null;

        state.cache.some(function (item) {
            if (item.id === id) {
                found = item;
                return true;
            }
            return false;
        });

        if (!found) {
            return false;
        }

        $('#noesia-swa-rem-id').val(found.id);
        $('#noesia-swa-rem-type').val(found.type);
        $('#noesia-swa-rem-due-date').val(found.dueDate);
        $('#noesia-swa-rem-due-time').val(found.dueTime);
        $('#noesia-swa-rem-related').val(found.related);
        $('#noesia-swa-rem-message').val(found.message);
        $('#noesia-swa-rem-delete').removeAttr('hidden');

        openReminderModal(null);
        return true;
    }

    function renderReminders() {
        var t = reminderStrings();
        var $list = $('#noesia-swa-reminders-items');
        var filters;
        var visible;
        var stats;
        var html = '';

        syncReminderBadge(state.cache);

        if (!$list.length) {
            return;
        }

        filters = reminderCollectFilters();
        visible = state.cache.filter(function (item) {
            return reminderMatches(item, filters);
        });
        stats = computeReminderStats(state.cache);

        $('#noesia-swa-rem-kpi-overdue').text(String(stats.overdue));
        $('#noesia-swa-rem-kpi-today').text(String(stats.today));
        $('#noesia-swa-rem-kpi-upcoming').text(String(stats.upcoming));
        $('#noesia-swa-rem-kpi-completed').text(String(stats.completed));

        if (!visible.length) {
            $list.html(
                '<div class="noesia-swa-card noesia-swa-rem-empty">' +
                    '<strong>' + escHtml(t.noFound) + '</strong>' +
                    '<p class="noesia-swa-muted">' + escHtml(t.noFoundSub) + '</p>' +
                '</div>'
            );

            if (state.cache.length) {
                remindersSetMessage(t.noMatches, false);
            } else {
                remindersSetMessage(t.noItems, false);
            }

            return;
        }

        visible.forEach(function (item) {
            html += '<article class="noesia-swa-rem-item" data-noesia-swa-rem-item="' + escHtml(item.id) + '">';
            html += '<div class="noesia-swa-rem-item__top">';
            html += '<div class="noesia-swa-rem-item__title-wrap">';
            html += '<div class="noesia-swa-rem-item__title">' + escHtml(item.type || t.untitled) + '</div>';
            html += '<div class="noesia-swa-rem-item__due-inline">' + escHtml(reminderFormatDue(item)) + '</div>';
            html += '</div>';
            html += reminderStatusBadge(item);
            html += '</div>';
            html += '<div class="noesia-swa-rem-item__meta">';
            html += '<span><strong>' + escHtml(t.due) + '</strong> ' + escHtml(reminderFormatDue(item)) + '</span>';

            if (item.related) {
                html += '<span><strong>' + escHtml(t.related) + '</strong> ' + escHtml(item.related) + '</span>';
            }

            html += '</div>';

            if (item.message) {
                html += '<div class="noesia-swa-rem-item__message">' + escHtml(item.message) + '</div>';
            }

            html += '<div class="noesia-swa-rem-item__actions">';
            html += '<button type="button" class="button" data-noesia-swa-rem-edit="' + escHtml(item.id) + '">Edit</button>';

            if (item.status === 'completed') {
                html += '<button type="button" class="button" data-noesia-swa-rem-toggle="' + escHtml(item.id) + '">Reopen</button>';
            } else {
                html += '<button type="button" class="button button-primary" data-noesia-swa-rem-toggle="' + escHtml(item.id) + '">Complete</button>';
            }

            html += '</div>';
            html += '</article>';
        });

        $list.html(html);

        if (visible.length === 1) {
            remindersSetMessage(t.visibleOne, false);
        } else {
            remindersSetMessage(t.visibleMany.replace('%d', String(visible.length)), false);
        }
    }

    function fetchReminders() {
        var t = reminderStrings();

        if (!hasUi()) {
            return $.Deferred().resolve(false).promise();
        }

        if (!ajaxUrl || !nonces.request) {
            state.cache = [];
            renderReminders();
            remindersSetMessage(t.loadError, true);
            return $.Deferred().reject().promise();
        }

        state.loading = true;

        return reminderAjax('noesia_swa_reminders_list', {})
            .done(function (resp) {
                if (!resp || !resp.success || !resp.data || !Array.isArray(resp.data.items)) {
                    remindersSetMessage(t.loadError, true);
                    state.cache = [];
                    renderReminders();
                    return;
                }

                state.cache = resp.data.items
                    .map(reminderNormalizeItem)
                    .filter(function (item) { return !!item; });

                state.cache.sort(function (a, b) {
                    var aDone = a.status === 'completed' ? 1 : 0;
                    var bDone = b.status === 'completed' ? 1 : 0;

                    if (aDone !== bDone) {
                        return aDone - bDone;
                    }

                    return reminderDueStamp(a) - reminderDueStamp(b);
                });

                renderReminders();
            })
            .fail(function () {
                state.cache = [];
                renderReminders();
                remindersSetMessage(t.loadError, true);
            })
            .always(function () {
                state.loading = false;
            });
    }

    function collectReminderForm() {
        return {
            post_id: String($('#noesia-swa-rem-id').val() || '').trim(),
            type: String($('#noesia-swa-rem-type').val() || '').trim(),
            due_date: String($('#noesia-swa-rem-due-date').val() || '').trim(),
            due_time: String($('#noesia-swa-rem-due-time').val() || '').trim(),
            related: String($('#noesia-swa-rem-related').val() || '').trim(),
            message: String($('#noesia-swa-rem-message').val() || '').trim()
        };
    }

    function saveReminderCurrent() {
        var t = reminderStrings();
        var payload = collectReminderForm();

        if (!payload.type && !payload.message) {
            remindersSetMessage(t.validateError, true);
            $('#noesia-swa-rem-type').trigger('focus');
            return $.Deferred().reject().promise();
        }

        remindersSetMessage('Saving reminder…', false);

        return reminderAjax('noesia_swa_reminders_save', payload)
            .done(function (resp) {
                if (!resp || !resp.success) {
                    remindersSetMessage((resp && resp.data && resp.data.message) ? String(resp.data.message) : t.saveError, true);
                    return;
                }

                resetReminderForm();
                closeReminderModal();
                fetchReminders();
                remindersSetMessage(payload.post_id ? t.updated : t.created, false);
            })
            .fail(function () {
                remindersSetMessage(t.saveError, true);
            });
    }

    function toggleReminder(id) {
        var t = reminderStrings();

        return reminderAjax('noesia_swa_reminders_toggle', {
            post_id: String(id || '').trim()
        })
            .done(function (resp) {
                if (!resp || !resp.success) {
                    remindersSetMessage((resp && resp.data && resp.data.message) ? String(resp.data.message) : t.toggleError, true);
                    return;
                }

                fetchReminders();
                remindersSetMessage(t.updated, false);
            })
            .fail(function () {
                remindersSetMessage(t.toggleError, true);
            });
    }

    function deleteReminderCurrent() {
        var t = reminderStrings();
        var postId = String($('#noesia-swa-rem-id').val() || '').trim();

        if (!postId) {
            return $.Deferred().resolve(false).promise();
        }

        remindersSetMessage('Deleting reminder…', false);

        return reminderAjax('noesia_swa_reminders_delete', {
            post_id: postId
        })
            .done(function (resp) {
                if (!resp || !resp.success) {
                    remindersSetMessage((resp && resp.data && resp.data.message) ? String(resp.data.message) : t.deleteError, true);
                    return;
                }

                resetReminderForm();
                closeReminderModal();
                fetchReminders();
                remindersSetMessage(t.deleted, false);
            })
            .fail(function () {
                remindersSetMessage(t.deleteError, true);
            });
    }

    function bindEvents() {
        if (state.bound) {
            return true;
        }

        state.bound = true;

        $(document)
            .off('.noesiaSwaReminders')
            .on('click.noesiaSwaReminders', '[data-noesia-swa-rem-focus-create]', function (e) {
                e.preventDefault();
                resetReminderForm();
                openReminderModal(this);
            })
            .on('click.noesiaSwaReminders', '[data-noesia-swa-rem-save]', function (e) {
                e.preventDefault();
                saveReminderCurrent();
            })
            .on('click.noesiaSwaReminders', '#noesia-swa-rem-cancel', function (e) {
                e.preventDefault();
                resetReminderForm();
                closeReminderModal();
                remindersSetMessage(reminderStrings().canceled, false);
            })
            .on('click.noesiaSwaReminders', '#noesia-swa-rem-delete', function (e) {
                e.preventDefault();
                deleteReminderCurrent();
            })
            .on('click.noesiaSwaReminders', '[data-noesia-swa-rem-edit]', function (e) {
                e.preventDefault();
                state.lastModalTrigger = this;
                fillReminderForm(String($(this).attr('data-noesia-swa-rem-edit') || ''));
            })
            .on('click.noesiaSwaReminders', '[data-noesia-swa-rem-toggle]', function (e) {
                e.preventDefault();
                toggleReminder(String($(this).attr('data-noesia-swa-rem-toggle') || ''));
            })
            .on('input.noesiaSwaReminders change.noesiaSwaReminders', '#noesia-swa-reminders-filter-status, #noesia-swa-reminders-filter-due, #noesia-swa-reminders-search', function () {
                renderReminders();
            })
            .on('change.noesiaSwaReminders', '#noesia-swa-reminders-view-mode', function () {
                applyViewMode($(this).is(':checked') ? 'grid' : 'classic');
            })
            .on('click.noesiaSwaReminders', '[data-noesia-swa-rem-close-modal]', function (e) {
                e.preventDefault();
                closeReminderModal();
            })
            .on('keydown.noesiaSwaReminders', function (e) {
                if (e.key === 'Escape' && state.modalOpen) {
                    closeReminderModal();
                }
            });

        return true;
    }

    function boot() {
        if (state.booted) {
            return true;
        }

        if (!hasUi()) {
            return false;
        }

        bindEvents();
        resetReminderForm();
        loadViewMode();
        applyViewMode(state.viewMode);
        state.booted = true;
        return true;
    }

    function init() {
        if (!boot()) {
            return false;
        }

        fetchReminders();
        return true;
    }

    function onSectionOpen(target) {
        if (String(target || 'reminders') !== 'reminders') {
            return false;
        }

        return init();
    }

    function onShow() {
        return onSectionOpen('reminders');
    }

    function show() {
        return onSectionOpen('reminders');
    }

    modules.reminders = {
        boot: boot,
        init: init,
        onSectionOpen: onSectionOpen,
        onShow: onShow,
        show: show,
        fetch: fetchReminders,
        render: renderReminders,
        resetForm: resetReminderForm,
        fillForm: fillReminderForm,
        saveCurrent: saveReminderCurrent,
        deleteCurrent: deleteReminderCurrent,
        toggle: toggleReminder,
        reminderStats: computeReminderStats,
        openModal: openReminderModal,
        closeModal: closeReminderModal,
        setViewMode: applyViewMode,
        getCache: function () {
            return state.cache.slice();
        }
    };

    boot();
})(window, jQuery);
