/**
 * Deactivation exit survey (plugins.php only).
 *
 * Intercepts the Encypher Provenance "Deactivate" link with a small,
 * dismissible modal offering four one-click reasons plus an optional note.
 * A reason click fires a best-effort telemetry beacon and then proceeds with
 * the real deactivation IMMEDIATELY; "Skip and deactivate" proceeds without
 * sending anything. The network call is never awaited and never blocks, so a
 * slow or offline API can never trap an admin on the plugins screen.
 * Dismissal (the close button, the backdrop, or Escape) means the admin
 * changed their mind: the modal closes and the plugin STAYS ACTIVE.
 *
 * Vanilla JS (no jQuery). The core is a dependency-injected factory so the
 * wiring contract is unit-testable with fake document/window/navigator/fetch.
 */
(function () {
    'use strict';

    var REASONS = ['connection_problems', 'too_complex', 'did_not_need', 'something_broke'];

    /**
     * Walk up from an event target to the nearest anchor element.
     */
    function closestAnchor(node) {
        while (node) {
            if (node.tagName === 'A' || node.nodeName === 'A') {
                return node;
            }
            node = node.parentNode;
        }
        return null;
    }

    function anchorHref(anchor) {
        if (!anchor) {
            return '';
        }
        var href = '';
        if (typeof anchor.getAttribute === 'function') {
            href = anchor.getAttribute('href') || '';
        }
        return href || anchor.href || '';
    }

    /**
     * True only for OUR plugin's deactivate link. WordPress builds the link as
     * ...?action=deactivate&plugin=<basename>... and url-encodes the slash in
     * the basename (%2F), so match either form.
     */
    function isOurDeactivateLink(anchor, config) {
        var href = anchorHref(anchor);
        if (!href || href.indexOf('action=deactivate') === -1) {
            return false;
        }
        var file = config.pluginFile || '';
        if (!file) {
            return false;
        }
        return href.indexOf(file) !== -1 || href.indexOf(encodeURIComponent(file)) !== -1;
    }

    function createSurvey(config, deps) {
        var doc = deps.document;
        var win = deps.window;
        var overlay = null;
        var textarea = null;
        var pendingHref = '';

        /**
         * Best-effort telemetry. Prefers navigator.sendBeacon (flushed by the
         * browser even during unload); falls back to a keepalive fetch. Returns
         * nothing and never throws: the caller ALWAYS proceeds regardless.
         */
        function sendFeedback(reason, comment) {
            try {
                var payload = JSON.stringify({
                    reason: REASONS.indexOf(reason) === -1 ? '' : reason,
                    comment: comment || ''
                });
                var nav = deps.navigator;
                if (nav && typeof nav.sendBeacon === 'function') {
                    // sendBeacon cannot set headers, so carry the REST nonce as
                    // a query arg (WordPress honours _wpnonce for REST auth).
                    var sep = config.restUrl.indexOf('?') === -1 ? '?' : '&';
                    var beaconUrl = config.restUrl + sep + '_wpnonce=' + encodeURIComponent(config.nonce || '');
                    var body = payload;
                    if (typeof deps.Blob === 'function') {
                        body = new deps.Blob([payload], { type: 'application/json' });
                    }
                    nav.sendBeacon(beaconUrl, body);
                    return;
                }
                if (typeof deps.fetch === 'function') {
                    var result = deps.fetch(config.restUrl, {
                        method: 'POST',
                        keepalive: true,
                        headers: {
                            'Content-Type': 'application/json',
                            'X-WP-Nonce': config.nonce || ''
                        },
                        body: payload
                    });
                    if (result && typeof result.catch === 'function') {
                        result.catch(function () {});
                    }
                }
            } catch (e) {
                // Telemetry is best-effort: swallow everything.
            }
        }

        /**
         * Navigate to the real deactivate URL immediately. Everything else in
         * this module exists only to reach here without ever blocking.
         */
        function proceed() {
            var href = pendingHref;
            close();
            if (href) {
                win.location.href = href;
            }
        }

        function close() {
            if (overlay && overlay.parentNode && typeof overlay.parentNode.removeChild === 'function') {
                overlay.parentNode.removeChild(overlay);
            } else if (overlay && typeof overlay.remove === 'function') {
                overlay.remove();
            }
            overlay = null;
            textarea = null;
            pendingHref = '';
        }

        function commentValue() {
            return textarea && typeof textarea.value === 'string' ? textarea.value : '';
        }

        function choose(reason) {
            sendFeedback(reason, commentValue());
            proceed();
        }

        function skip() {
            proceed();
        }

        function el(tag, props) {
            var node = doc.createElement(tag);
            props = props || {};
            Object.keys(props).forEach(function (key) {
                if (key === 'text') {
                    node.textContent = props[key];
                } else if (key === 'html') {
                    node.innerHTML = props[key];
                } else if (typeof node.setAttribute === 'function' && (key === 'type' || key === 'role' || key === 'rows' || key === 'placeholder' || key === 'aria-label')) {
                    node.setAttribute(key, props[key]);
                } else {
                    node[key] = props[key];
                }
            });
            return node;
        }

        function buildModal() {
            var strings = config.strings || {};
            var labels = config.reasons || {};

            overlay = el('div', { className: 'encypher-deact-overlay', role: 'dialog', 'aria-label': strings.title || 'Deactivate Encypher Provenance' });
            overlay.addEventListener('click', function (event) {
                // Backdrop click (outside the dialog) cancels: the admin
                // changed their mind, so the plugin stays active.
                if (event && event.target === overlay) {
                    close();
                }
            });

            var dialog = el('div', { className: 'encypher-deact-dialog' });

            var closeBtn = el('button', { className: 'encypher-deact-close', type: 'button', 'aria-label': strings.dismiss || 'Close', text: '\u00d7' });
            closeBtn.addEventListener('click', function (event) {
                if (event && typeof event.preventDefault === 'function') { event.preventDefault(); }
                close();
            });
            dialog.appendChild(closeBtn);

            dialog.appendChild(el('h2', { className: 'encypher-deact-title', text: strings.title || 'Quick question before you go' }));
            dialog.appendChild(el('p', { className: 'encypher-deact-subtitle', text: strings.subtitle || 'What is making you deactivate Encypher Provenance?' }));

            var list = el('div', { className: 'encypher-deact-reasons' });
            REASONS.forEach(function (reason) {
                var btn = el('button', { className: 'encypher-deact-reason button', type: 'button', text: labels[reason] || reason });
                btn.setAttribute('data-reason', reason);
                btn.addEventListener('click', function (event) {
                    if (event && typeof event.preventDefault === 'function') { event.preventDefault(); }
                    choose(reason);
                });
                list.appendChild(btn);
            });
            dialog.appendChild(list);

            textarea = el('textarea', { className: 'encypher-deact-comment', rows: '3', placeholder: strings.placeholder || 'Anything else? (optional)' });
            dialog.appendChild(textarea);

            var skipBtn = el('button', { className: 'encypher-deact-skip button-link', type: 'button', text: strings.skip || 'Skip and deactivate' });
            skipBtn.addEventListener('click', function (event) {
                if (event && typeof event.preventDefault === 'function') { event.preventDefault(); }
                skip();
            });
            dialog.appendChild(skipBtn);

            overlay.appendChild(dialog);
            doc.body.appendChild(overlay);
        }

        function open(href) {
            pendingHref = href || '';
            if (overlay) {
                return;
            }
            buildModal();
        }

        function onDocumentClick(event) {
            var anchor = closestAnchor(event && event.target);
            if (!isOurDeactivateLink(anchor, config)) {
                return;
            }
            if (typeof event.preventDefault === 'function') {
                event.preventDefault();
            }
            open(anchorHref(anchor));
        }

        function onKeydown(event) {
            if (overlay && event && (event.key === 'Escape' || event.keyCode === 27)) {
                close();
            }
        }

        function bind() {
            doc.addEventListener('click', onDocumentClick);
            doc.addEventListener('keydown', onKeydown);
            return controller;
        }

        var controller = {
            bind: bind,
            open: open,
            choose: choose,
            skip: skip,
            close: close,
            sendFeedback: sendFeedback,
            isOurDeactivateLink: function (anchor) { return isOurDeactivateLink(anchor, config); },
            handleDocumentClick: onDocumentClick
        };
        return controller;
    }

    function boot(win) {
        var config = win && win.EncypherDeactivationSurvey;
        if (!config || !config.restUrl || !config.pluginFile) {
            return;
        }
        var deps = {
            document: win.document,
            window: win,
            navigator: win.navigator,
            fetch: win.fetch ? win.fetch.bind(win) : undefined,
            Blob: win.Blob
        };
        createSurvey(config, deps).bind();
    }

    // Node/test harness entry point.
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = { createSurvey: createSurvey, isOurDeactivateLink: isOurDeactivateLink, closestAnchor: closestAnchor, REASONS: REASONS };
    }

    // Browser entry point.
    if (typeof window !== 'undefined' && typeof document !== 'undefined') {
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function () { boot(window); });
        } else {
            boot(window);
        }
    }
})();
