/**
 * Diálogos HTML5 (<dialog>) en lugar de alert/confirm/prompt nativos.
 * Cola serializada; estilos en assets/css/app-dialog.css (variables con fallback).
 */
(function (global) {
    'use strict';

    var tail = Promise.resolve();
    var dlg = null;
    var iconEl = null;
    var titleEl = null;
    var titleBarEl = null;
    var closeBtn = null;
    var msgEl = null;
    var fieldWrap = null;
    var labelEl = null;
    var inputEl = null;
    var okBtn = null;
    var cancelBtn = null;
    var actionsEl = null;
    var extrasEl = null;
    var toggleInputEl = null;
    var toggleLabelEl = null;
    var toggleHintEl = null;
    var toggleChangeHandler = null;

    /**
     * Heurística en español + inglés para inferir el tipo de mensaje.
     * Devuelve: 'success' | 'error' | 'warning' | 'info' | 'question' | 'danger' | 'trash'
     *  - danger: acción destructiva irreversible (eliminar permanente, vaciar papelera, formatear…)
     *  - trash:  acción reversible (mover a papelera, ocultar, archivar…)
     */
    function detectFeedbackType(message, mode) {
        if (mode === 'prompt') return 'question';
        var s = String(message == null ? '' : message).toLowerCase();
        var isQuestion = mode === 'confirm' || /[¿?]/.test(s);
        if (isQuestion) {
            // Mover/enviar a papelera => recuperable
            if (/(mover.*papelera|enviar.*papelera|a la papelera|to (the )?(recycle|trash)|move to (trash|recycle)|send to (trash|recycle))/.test(s)) return 'trash';
            // Acciones destructivas irreversibles
            if (/(permanent|definitiv|sin recuperaci|no podr[áa]n? (ser )?recuperar|cannot be recovered|cannot be undone|vaciar|empty (the )?(trash|recycle)|formatear|format reinstall|destruir|borrar de forma|wipe)/.test(s)) return 'danger';
            // Eliminar/borrar/quitar/descartar genéricos
            if (/(eliminar|borrar|quitar|remover|descartar|reset|restablecer|delete|remove|discard|reset)/.test(s)) return 'danger';
            if (/(papelera|trash|recycle bin)/.test(s)) return 'trash';
            return 'question';
        }
        if (/(error|fall(o|ó|a|aron)|no se pudo|no se puede|incorrect|inv[áa]lid|denegad|rechazad|prohibid|bloquead|caduca|expirad|expir[oó]|failed|cannot|can'?t|denied|forbidden|invalid)/.test(s)) return 'error';
        if (/(advertencia|atenci[oó]n|cuidado|warning|sin guardar|demasiad|requer|obligator|necesit|debes|debe iniciar|unsaved|required|attention)/.test(s)) return 'warning';
        if (/(guardad|creado|enviad|copiad|[éeE]xito|exitoso|completad|registrad|actualizad|configurad|listo|hecho|aplicad|generad|saved|created|sent|copied|success|completed|updated|configured|done|ready)/.test(s)) return 'success';
        return 'info';
    }

    // Font Awesome 5 (sintaxis compatible con la versión local incluida en assets/vendor/font-awesome).
    var FEEDBACK_ICON_MAP = {
        success: 'fas fa-check-circle',
        error: 'fas fa-times-circle',
        warning: 'fas fa-exclamation-triangle',
        info: 'fas fa-info-circle',
        question: 'fas fa-question-circle',
        danger: 'fas fa-trash-alt',
        trash: 'fas fa-trash-alt',
    };

    var FEEDBACK_TITLE_MAP = {
        success: 'Listo',
        error: 'Error',
        warning: 'Atención',
        info: 'Aviso',
        question: 'Confirmar',
        danger: 'Eliminar',
        trash: 'Mover a papelera',
    };

    var FEEDBACK_EMOJI_MAP = {
        success: '✅',
        error: '⛔',
        warning: '⚠️',
        info: 'ℹ️',
        question: '❓',
        danger: '🗑️',
        trash: '🗑️',
    };

    function feedbackIconClass(type) {
        return FEEDBACK_ICON_MAP[type] || FEEDBACK_ICON_MAP.info;
    }

    function feedbackTitle(type) {
        return FEEDBACK_TITLE_MAP[type] || FEEDBACK_TITLE_MAP.info;
    }

    function feedbackEmoji(type) {
        return FEEDBACK_EMOJI_MAP[type] || '';
    }

    function ensureDialog() {
        if (dlg) return;
        dlg = document.createElement('dialog');
        dlg.className = 'grid-app-dialog';
        dlg.setAttribute('aria-modal', 'true');
        dlg.innerHTML =
            '<div class="grid-app-dialog-panel">' +
            '<div class="grid-app-dialog-titlebar" id="gridAppDialogTitlebar">' +
            '<div class="grid-app-dialog-titlebar-text">' +
            '<span class="grid-app-dialog-titlebar-icon" id="gridAppDialogIcon" aria-hidden="true"><i class="fas fa-info-circle"></i></span>' +
            '<h2 class="grid-app-dialog-title" id="gridAppDialogTitle"></h2>' +
            '</div>' +
            '<button type="button" class="grid-app-dialog-close" id="gridAppDialogClose" data-act="close" aria-label="Cerrar" title="Cerrar">' +
            '<i class="fas fa-times" aria-hidden="true"></i>' +
            '</button>' +
            '</div>' +
            '<div class="grid-app-dialog-body">' +
            '<p class="grid-app-dialog-message" id="gridAppDialogMessage"></p>' +
            '<div class="grid-app-dialog-extras" id="gridAppDialogExtras" hidden>' +
            '<div class="grid-app-dialog-toggle3d-wrap">' +
            '<label class="grid-app-dialog-toggle3d">' +
            '<input type="checkbox" class="grid-app-dialog-toggle3d__input" id="gridAppDialogToggle" />' +
            '<span class="grid-app-dialog-toggle3d__track" aria-hidden="true"><span class="grid-app-dialog-toggle3d__knob"></span></span>' +
            '<span class="grid-app-dialog-toggle3d__label" id="gridAppDialogToggleLabel"></span>' +
            '</label>' +
            '<p class="grid-app-dialog-toggle3d__hint" id="gridAppDialogToggleHint"></p>' +
            '</div>' +
            '</div>' +
            '<div class="grid-app-dialog-field" id="gridAppDialogFieldWrap" hidden>' +
            '<label class="grid-app-dialog-label" id="gridAppDialogLabel" for="gridAppDialogInput"></label>' +
            '<input class="grid-app-dialog-input" id="gridAppDialogInput" autocomplete="off" />' +
            '</div>' +
            '</div>' +
            '<div class="grid-app-dialog-actions" id="gridAppDialogActions">' +
            '<button type="button" class="grid-app-dialog-btn grid-app-dialog-btn--secondary" data-act="cancel">Cancelar</button>' +
            '<button type="button" class="grid-app-dialog-btn grid-app-dialog-btn--primary" data-act="ok">Aceptar</button>' +
            '</div>' +
            '</div>';
        document.body.appendChild(dlg);
        titleBarEl = dlg.querySelector('#gridAppDialogTitlebar');
        iconEl = dlg.querySelector('#gridAppDialogIcon');
        titleEl = dlg.querySelector('#gridAppDialogTitle');
        closeBtn = dlg.querySelector('#gridAppDialogClose');
        msgEl = dlg.querySelector('#gridAppDialogMessage');
        fieldWrap = dlg.querySelector('#gridAppDialogFieldWrap');
        labelEl = dlg.querySelector('#gridAppDialogLabel');
        inputEl = dlg.querySelector('#gridAppDialogInput');
        okBtn = dlg.querySelector('[data-act="ok"]');
        cancelBtn = dlg.querySelector('[data-act="cancel"]');
        actionsEl = dlg.querySelector('#gridAppDialogActions');
        extrasEl = dlg.querySelector('#gridAppDialogExtras');
        toggleInputEl = dlg.querySelector('#gridAppDialogToggle');
        toggleLabelEl = dlg.querySelector('#gridAppDialogToggleLabel');
        toggleHintEl = dlg.querySelector('#gridAppDialogToggleHint');
    }

    function clearToggleExtras() {
        if (toggleInputEl && toggleChangeHandler) {
            toggleInputEl.removeEventListener('change', toggleChangeHandler);
            toggleChangeHandler = null;
        }
        if (extrasEl) extrasEl.hidden = true;
        if (toggleInputEl) toggleInputEl.checked = false;
        if (toggleLabelEl) toggleLabelEl.textContent = '';
        if (toggleHintEl) toggleHintEl.textContent = '';
    }

    function setupToggleExtras(toggleOpts) {
        if (!extrasEl || !toggleInputEl) return;
        var t = toggleOpts || {};
        extrasEl.hidden = false;
        if (toggleLabelEl) toggleLabelEl.textContent = t.label != null ? String(t.label) : '';
        var checked = !!t.checked;
        toggleInputEl.checked = checked;
        function refreshHint() {
            if (!toggleHintEl) return;
            var on = !!toggleInputEl.checked;
            if (on && t.hintOn != null) toggleHintEl.textContent = String(t.hintOn);
            else if (!on && t.hintOff != null) toggleHintEl.textContent = String(t.hintOff);
            else if (t.hint != null) toggleHintEl.textContent = String(t.hint);
            else toggleHintEl.textContent = '';
        }
        refreshHint();
        toggleChangeHandler = function () { refreshHint(); };
        toggleInputEl.addEventListener('change', toggleChangeHandler);
    }

    function queue(fn) {
        var next = tail.then(fn);
        tail = next.catch(function () {});
        return next;
    }

    function closeDialog() {
        try {
            if (dlg && dlg.open) dlg.close();
        } catch (_) {}
    }

    /**
     * @param {'alert'|'confirm'|'prompt'} mode
     * @param {string} message
     * @param {{ defaultValue?: string, inputType?: string, okLabel?: string, cancelLabel?: string, title?: string, type?: 'success'|'error'|'warning'|'info'|'question', toggle?: { label?: string, hint?: string, hintOn?: string, hintOff?: string, checked?: boolean }, resolveToggle?: boolean }} [opts]
     */
    function openDialog(mode, message, opts) {
        opts = opts || {};
        ensureDialog();
        return new Promise(function (resolve) {
            var finished = false;
            var withToggle = !!(opts.toggle && mode === 'confirm' && opts.resolveToggle);
            function finish(val) {
                if (finished) return;
                finished = true;
                clearToggleExtras();
                closeDialog();
                resolve(val);
            }
            function finishToggle(confirmed) {
                if (!withToggle) {
                    finish(!!confirmed);
                    return;
                }
                finish({
                    confirmed: !!confirmed,
                    checked: toggleInputEl ? !!toggleInputEl.checked : false,
                });
            }

            dlg.dataset.mode = mode;
            var type = opts.type || detectFeedbackType(message, mode);
            dlg.dataset.type = type;
            if (iconEl) {
                iconEl.innerHTML = '<i class="' + feedbackIconClass(type) + '" aria-hidden="true"></i>';
            }
            var titleText = opts.title != null ? String(opts.title) : feedbackTitle(type);
            titleEl.textContent = titleText;
            titleEl.hidden = false;
            titleEl.removeAttribute('aria-hidden');
            dlg.setAttribute('aria-labelledby', 'gridAppDialogTitle');
            msgEl.textContent = String(message == null ? '' : message);
            dlg.setAttribute('aria-describedby', 'gridAppDialogMessage');
            clearToggleExtras();
            if (withToggle) {
                setupToggleExtras(opts.toggle);
                dlg.setAttribute('aria-describedby', 'gridAppDialogMessage gridAppDialogToggleHint');
            }

            var defaultOk = type === 'danger' ? 'Eliminar' : type === 'trash' ? 'Mover a papelera' : 'Aceptar';
            if (mode === 'prompt') {
                fieldWrap.hidden = false;
                labelEl.textContent = opts.label != null ? String(opts.label) : '';
                inputEl.value = opts.defaultValue != null ? String(opts.defaultValue) : '';
                inputEl.type = opts.inputType === 'password' ? 'password' : 'text';
                cancelBtn.style.display = '';
                okBtn.textContent = opts.okLabel || 'Aceptar';
                cancelBtn.textContent = opts.cancelLabel || 'Cancelar';
            } else if (mode === 'confirm') {
                fieldWrap.hidden = true;
                cancelBtn.style.display = '';
                okBtn.textContent = opts.okLabel || defaultOk;
                cancelBtn.textContent = opts.cancelLabel || 'Cancelar';
            } else {
                fieldWrap.hidden = true;
                cancelBtn.style.display = 'none';
                okBtn.textContent = opts.okLabel || 'Aceptar';
            }

            function unbind() {
                dlg.removeEventListener('close', onClose);
                okBtn.removeEventListener('click', onOk);
                cancelBtn.removeEventListener('click', onCancelClick);
                if (closeBtn) closeBtn.removeEventListener('click', onCancelClick);
            }
            function onOk() {
                unbind();
                if (mode === 'prompt') {
                    finish(inputEl.value);
                } else if (mode === 'confirm') {
                    finishToggle(true);
                } else {
                    finish(undefined);
                }
            }
            function onCancelClick() {
                unbind();
                if (mode === 'confirm') finishToggle(false);
                else if (mode === 'prompt') finish(null);
                else finish(undefined);
            }
            function onClose() {
                okBtn.removeEventListener('click', onOk);
                cancelBtn.removeEventListener('click', onCancelClick);
                if (closeBtn) closeBtn.removeEventListener('click', onCancelClick);
                if (finished) return;
                if (mode === 'confirm') finishToggle(false);
                else if (mode === 'prompt') finish(null);
                else finish(undefined);
            }

            dlg.addEventListener('close', onClose, { once: true });
            okBtn.addEventListener('click', onOk);
            cancelBtn.addEventListener('click', onCancelClick);
            if (closeBtn) closeBtn.addEventListener('click', onCancelClick);

            try {
                if (typeof dlg.showModal === 'function') {
                    dlg.showModal();
                } else {
                    if (mode === 'confirm' && withToggle) {
                        finishToggle(!!global.confirm(message));
                    } else {
                        finish(mode === 'confirm' ? global.confirm(message) : mode === 'prompt' ? global.prompt(message, opts.defaultValue) : void global.alert(message));
                    }
                    return;
                }
            } catch (e) {
                if (mode === 'confirm' && withToggle) finishToggle(false);
                else finish(mode === 'confirm' ? false : mode === 'prompt' ? null : undefined);
                return;
            }

            if (mode === 'prompt') {
                setTimeout(function () {
                    try {
                        inputEl.focus();
                        inputEl.select();
                    } catch (_) {}
                }, 0);
            } else {
                setTimeout(function () {
                    try {
                        okBtn.focus();
                    } catch (_) {}
                }, 0);
            }
        });
    }

    /**
     * @param {string} message
     * @param {{ type?: 'success'|'error'|'warning'|'info'|'question', title?: string, okLabel?: string }} [opts]
     */
    function alert(message, opts) {
        return queue(function () {
            return openDialog('alert', message, opts || {});
        });
    }

    /**
     * @param {string} message
     * @param {{ type?: 'success'|'error'|'warning'|'info'|'question', title?: string, okLabel?: string, cancelLabel?: string }} [opts]
     */
    function confirm(message, opts) {
        return queue(function () {
            return openDialog('confirm', message, opts || {});
        });
    }

    /**
     * Confirmación con interruptor opcional (p. ej. conservar documentos al formatear).
     * @param {string} message
     * @param {{ label?: string, hint?: string, hintOn?: string, hintOff?: string, checked?: boolean }} toggleOpts
     * @param {{ type?: string, title?: string, okLabel?: string, cancelLabel?: string }} [opts]
     * @returns {Promise<{ confirmed: boolean, checked: boolean }>}
     */
    function confirmToggle(message, toggleOpts, opts) {
        return queue(function () {
            return openDialog('confirm', message, Object.assign({}, opts || {}, {
                toggle: toggleOpts || {},
                resolveToggle: true,
            }));
        });
    }

    /**
     * @param {string} message
     * @param {string} [defaultValue]
     * @param {{ inputType?: string, label?: string, type?: 'success'|'error'|'warning'|'info'|'question', title?: string }} [opts]
     */
    function prompt(message, defaultValue, opts) {
        return queue(function () {
            var o = Object.assign({}, opts || {}, { defaultValue: defaultValue });
            return openDialog('prompt', message, o);
        });
    }

    global.appDialog = {
        alert: alert,
        confirm: confirm,
        confirmToggle: confirmToggle,
        prompt: prompt,
        detectFeedbackType: detectFeedbackType,
        feedbackIconClass: feedbackIconClass,
        feedbackTitle: feedbackTitle,
        feedbackEmoji: feedbackEmoji,
    };
})(typeof window !== 'undefined' ? window : this);
