/**
 * AIEO Checkout Notice Modal — accessibility-first wrapper that hoists
 * WC checkout notices into a focus-trapped modal dialog instead of
 * scattering them as inline banners. Migrated from om-checkout-handling.
 *
 * Listens to:
 *   - WC's `checkout_error` and `updated_checkout` body events
 *   - DOM mutations (catches block-checkout async error renders)
 *   - A bootstrap `window.__OM_WC_NOTICES_HTML` global the server can
 *     populate in the footer to surface server-side notices on first
 *     paint (without re-rendering them inline).
 */
(function($){
    if (typeof $ === "undefined") return;

    var __ = ( window.wp && window.wp.i18n && window.wp.i18n.__ ) ? window.wp.i18n.__ : function (s) { return s; };
    var _x = ( window.wp && window.wp.i18n && window.wp.i18n._x ) ? window.wp.i18n._x : function (s) { return s; };
    var _n = ( window.wp && window.wp.i18n && window.wp.i18n._n ) ? window.wp.i18n._n : function (s, p, n) { return n === 1 ? s : p; };
    var _sprintf = ( window.wp && window.wp.i18n && window.wp.i18n.sprintf ) ? window.wp.i18n.sprintf : function (s) { return s; };

    window.omWcModalTitle = window.omWcModalTitle || __('Checkout errors', 'ai-eshop-optimizer');

    var state = {
        dismissed: false,
        lastHtmlSig: "",
        prevActive: null
    };

    function ensureModal(){
        if ($(".om-wc-modal").length) return;
        $("body").append(
            '<div class="om-wc-modal-overlay" aria-hidden="true" style="display:none"></div>' +
            '<div class="om-wc-modal" role="dialog" aria-modal="true" aria-labelledby="om-wc-modal-title" tabindex="-1" style="display:none">' +
                '<div class="om-wc-modal-header">' +
                    '<h3 id="om-wc-modal-title" class="om-wc-modal-title">' + (window.omWcModalTitle || __('Please review the messages', 'ai-eshop-optimizer')) + '</h3>' +
                    '<button type="button" class="om-wc-modal-close" aria-label="' + __('Close', 'ai-eshop-optimizer') + '">&times;</button>' +
                '</div>' +
                '<div class="om-wc-modal-body"></div>' +
            '</div>'
        );
    }

    function trapFocus(){
        var $modal = $(".om-wc-modal");
        var $f = $modal.find("button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])").filter(":visible");
        if (!$f.length) return;
        var first = $f.first()[0], last = $f.last()[0];
        $modal.on("keydown.omtrap", function(e){
            if (e.key !== "Tab") return;
            if (e.shiftKey && document.activeElement === first){ e.preventDefault(); last.focus(); }
            else if (!e.shiftKey && document.activeElement === last){ e.preventDefault(); first.focus(); }
        });
    }
    function untrapFocus(){
        $(".om-wc-modal").off("keydown.omtrap");
    }

    function signature(html){
        return (html || "").replace(/\s+/g,' ').trim();
    }

    function openModal(html){
        ensureModal();
        state.prevActive = document.activeElement;
        $(".om-wc-modal-body").html(html);
        $(".om-wc-modal-overlay").fadeIn(120);
        $(".om-wc-modal").fadeIn(120, function(){ $(".om-wc-modal").focus(); });
        $("body").addClass("om-wc-notice-open");
        trapFocus();
        state.dismissed = false;
        state.lastHtmlSig = signature(html);
    }

    function closeModal(){
        $(".om-wc-modal, .om-wc-modal-overlay").fadeOut(120);
        $("body").removeClass("om-wc-notice-open");
        untrapFocus();
        if (state.prevActive && typeof state.prevActive.focus === "function") {
            try { state.prevActive.focus(); } catch(e){}
        }
        state.dismissed = true;
    }

    $(document).on("click", ".om-wc-modal-close, .om-wc-modal-overlay", closeModal);
    $(document).on("keydown", function(e){ if (e.key === "Escape") closeModal(); });
    $(document).on("submit", "form.checkout", function(){ state.dismissed = false; state.lastHtmlSig = ""; });

    function enhanceHtmlLinks(escapedHtml){
        // Make "terms and conditions" mentions click-jumpable to the
        // checkbox so the user can fix the error without scrolling.
        escapedHtml = escapedHtml.replace(/accept the terms and conditions/i, '<a href="#terms-field" class="om-jump-terms">$&</a>');
        escapedHtml = escapedHtml.replace(/όρους(?:\s+και\s+)?προϋποθέσεις/gi, '<a href="#terms-field" class="om-jump-terms">$&</a>');
        return escapedHtml;
    }

    $(document).on('click', '.om-jump-terms', function(e){
        e.preventDefault();
        closeModal();
        var $target = $('#terms-field');
        if (!$target.length) {
            $target = $('[name="terms"]').closest('p, div, li').first();
        }
        if ($target.length) {
            $('html, body').animate({scrollTop: $target.offset().top - 80}, 200);
            var $cb = $target.find('input[type="checkbox"], input[name="terms"]').first();
            if ($cb.length) $cb.focus();
        }
    });

    function buildModalContentFromDom(){
        var messages = [];
        var seen = new Set();

        function normalize(txt){ return (txt || '').replace(/\s+/g,' ').trim(); }

        function pushMsg(type, txt){
            txt = normalize(txt);
            if (!txt) return;
            // Drop super-strings already covered by a more specific message,
            // and skip new strings that are subsets of existing ones.
            for (var i = messages.length - 1; i >= 0; i--) {
                var m = messages[i];
                if (m.type !== type) continue;
                if (m.text.indexOf(txt) !== -1 && m.text !== txt) messages.splice(i, 1);
            }
            for (var j = 0; j < messages.length; j++) {
                var n = messages[j];
                if (n.type === type && txt.indexOf(n.text) !== -1 && txt !== n.text) return;
            }
            var key = type + '|' + txt;
            if (seen.has(key)) return;
            seen.add(key);
            messages.push({ type: type, text: txt });
        }

        function splitIntoMessages(type, txt){
            txt = normalize(txt);
            if (!txt) return;
            // Split sentences glued together by WC's notice formatter so
            // each error reads as a separate bullet in the modal.
            var parts = txt.split(/(?<=[\.\!\;])\s+(?=[A-ZΑ-ΩΆΈΉΊΌΎΏ])/g)
                .map(normalize)
                .filter(Boolean);
            if (parts.length <= 1) pushMsg(type, txt);
            else parts.forEach(function(p){ pushMsg(type, p); });
        }

        var $scope = $('body').not('.om-wc-modal *');

        $scope.find(".woocommerce-NoticeGroup-checkout, .woocommerce-notices-wrapper").each(function(){
            var $wrap = $(this);
            $wrap.find(".woocommerce-error").each(function(){
                var $el = $(this), $li = $el.find('li');
                if ($li.length){ $li.each(function(){ splitIntoMessages('error', $(this).text()); }); }
                else { splitIntoMessages('error', $el.text()); }
            });
            $wrap.find(".woocommerce-message").each(function(){
                var $el = $(this), $li = $el.find('li');
                if ($li.length){ $li.each(function(){ splitIntoMessages('message', $(this).text()); }); }
                else { splitIntoMessages('message', $el.text()); }
            });
            $wrap.find(".woocommerce-info").each(function(){
                var $el = $(this), $li = $el.find('li');
                if ($li.length){ $li.each(function(){ splitIntoMessages('info', $(this).text()); }); }
                else { splitIntoMessages('info', $el.text()); }
            });
            $wrap.find("[role='alert']").each(function(){
                splitIntoMessages('error', $(this).text());
            });
        });

        // Block-checkout notice banners — different DOM, same intent.
        $scope.find(".wc-block-components-notice-banner.is-error, .wc-block-components-notice-banner[role='alert']")
            .each(function(){ splitIntoMessages('error', $(this).text()); });
        $scope.find(".wc-block-components-notice-banner.is-info")
            .each(function(){ splitIntoMessages('info', $(this).text()); });
        $scope.find(".wc-block-components-notice-banner.is-success")
            .each(function(){ splitIntoMessages('message', $(this).text()); });

        if (!messages.length) return "";

        var html = '<div class="om-wc-notices">';
        for (var i=0; i<messages.length; i++){
            var m = messages[i];
            // Neutral classes (NOT WC's `.woocommerce-error` etc.) so the rows
            // are styled solely by aieo-checkout-modal.css — no pink box, no
            // misaligned WC icon-font glyph, no inline overrides.
            var cls = (m.type === 'error' ? 'om-wc-notice--error' :
                       (m.type === 'info'  ? 'om-wc-notice--info' : 'om-wc-notice--success'));
            var safe = $('<div>').text(m.text).html();
            safe = enhanceHtmlLinks(safe);
            html += '<div class="om-wc-notice ' + cls + '">'
                 +  '<div class="om-wc-notice-text">' + safe + '</div>'
                 +  '</div>';
        }
        html += '</div>';
        return html;
    }

    function maybeOpenFromDom(){
        var html = buildModalContentFromDom();
        if (!html) return;
        var sig = signature(html);
        if (!state.dismissed && sig !== state.lastHtmlSig){
            openModal(html);
        }
    }

    $(document.body).on("checkout_error", function(){ maybeOpenFromDom(); });
    $(document.body).on("updated_checkout", function(){ maybeOpenFromDom(); });

    if (window.MutationObserver){
        var t = null;
        new MutationObserver(function(){
            if (t) clearTimeout(t);
            t = setTimeout(maybeOpenFromDom, 80);
        }).observe(document.body, {childList:true, subtree:true});
    }

    // Server-side bootstrap — the footer-injected JSON gives us notices
    // that were already flushed by `wc_print_notices()` server-side, so
    // first paint isn't a flash of inline notices.
    if (window.__OM_WC_NOTICES_HTML && window.__OM_WC_NOTICES_HTML.length){
        var tmp = document.createElement('div');
        tmp.innerHTML = window.__OM_WC_NOTICES_HTML;
        window.__OM_WC_NOTICES_HTML = "";
        var holder = document.createElement('div');
        holder.style.display = 'none';
        holder.className = 'om-wc-temp-holder';
        holder.appendChild(tmp);
        document.body.appendChild(holder);
        maybeOpenFromDom();
        $(holder).remove();
    }
})(jQuery);
