// Shared admin settings panel JS — runs inside the MutationObserver-injected panel.
//
// Responsibilities:
//   - Populate the Server Group dropdown from the addon's AJAX endpoint.
//   - Pre-select data-saved values on selects that were rendered before their
//     options were available (server group, email templates).
//   - Keep the tabs working inside the injected <tr>.

(function(){
    // Admin module URL, used to reach the addon's AJAX controllers.
    // We don't know the customadminpath at render time, so detect it from the
    // current URL — configproducts.php always lives under the same admin path.
    var adminPath = (window.location.pathname.match(/^\/[^\/]+/) || [''])[0];
    var addonUrl = window.location.origin + adminPath + '/addonmodules.php?module=puq_web_hosting';

    function ajax(action, data, cb) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', addonUrl + '&ajax=' + encodeURIComponent(action) + (data ? '&' + data : ''), true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState !== 4) return;
            try { cb(JSON.parse(xhr.responseText)); }
            catch(e) { cb({status:'error', msg:'parse error'}); }
        };
        xhr.send();
    }

    // ---- Self-contained tab switcher ------------------------------------
    // The settings panel is injected into the product-edit page AFTER load
    // (via the AdminAreaFooterOutput MutationObserver). The host WHMCS
    // Bootstrap "tab" data-api binds on page load and does NOT pick up our
    // dynamically-injected [data-toggle="tab"] links — on older WHMCS admin
    // themes this left every tab past "General" unreachable, so the product
    // settings appeared not to display. Drive the tabs ourselves with plain
    // DOM so it works on every WHMCS / Bootstrap / jQuery version, with no
    // dependency on the host's tab plugin.
    var panel = document.getElementById('puqModuleSettings');
    var tabShownCbs = {};

    function onTabShown(targetSel, cb) {
        (tabShownCbs[targetSel] = tabShownCbs[targetSel] || []).push(cb);
    }

    function activateTab(targetSel) {
        if (!panel) return;
        var link = panel.querySelector('.puq-tabs a[href="' + targetSel + '"]');
        var pane = panel.querySelector(targetSel);
        if (!link || !pane) return;
        var lis = panel.querySelectorAll('.puq-tabs > li');
        for (var i = 0; i < lis.length; i++) lis[i].classList.remove('active');
        if (link.parentNode) link.parentNode.classList.add('active');
        var panes = panel.querySelectorAll('.tab-content > .tab-pane');
        for (var k = 0; k < panes.length; k++) panes[k].classList.remove('active');
        pane.classList.add('active');
        var cbs = tabShownCbs[targetSel];
        if (cbs) cbs.forEach(function (cb) { try { cb(); } catch (e) {} });
    }

    if (panel) {
        panel.addEventListener('click', function (e) {
            var a = e.target && e.target.closest
                ? e.target.closest('.puq-tabs a[data-toggle="tab"]')
                : null;
            if (!a || !panel.contains(a)) return;
            // Take over from (and suppress) any host Bootstrap tab handler so
            // the two don't fight over the active classes.
            e.preventDefault();
            e.stopPropagation();
            var href = a.getAttribute('href');
            if (href && href.charAt(0) === '#') activateTab(href);
        });
    }

    function setSelectValue(selectEl) {
        var saved = selectEl.getAttribute('data-saved');
        if (saved == null || saved === '') return;
        for (var i = 0; i < selectEl.options.length; i++) {
            if (selectEl.options[i].value === String(saved)) {
                selectEl.selectedIndex = i;
                return;
            }
        }
    }

    // Load server groups
    var sel = document.getElementById('puq-sel-group');
    if (sel) {
        ajax('listServerGroups', null, function(r) {
            if (r && r.status === 'success' && Array.isArray(r.data)) {
                r.data.forEach(function(g) {
                    var opt = document.createElement('option');
                    opt.value = g.id;
                    opt.textContent = g.name;
                    sel.appendChild(opt);
                });
                setSelectValue(sel);
            }
        });
    }

    // Pre-select email-template dropdowns (their <option>s were rendered server-side)
    Array.prototype.forEach.call(document.querySelectorAll('.puq-email-tpl'), setSelectValue);

    // Deployment mode (split / unified / vanity) — toggle visibility of:
    //   - Account-limits tab nav item (shown only in unified)
    //   - Vanity-limits tab nav item (shown only in vanity)
    //   - any .puq-split-only field inside Web / Mail limits (hidden in
    //     unified AND vanity — both replace the per-role disk/bw/backups)
    // Changing the radio NEVER strips values from hidden inputs so the admin
    // can flip between modes without losing entered numbers; resolveLimits
    // simply ignores the irrelevant set on save.

    // Vanity relocation: a handful of Web/Mail fields (cron, databases, FTP,
    // PHP version, auto-SSL, mail rate limit) move INTO the Vanity tab when
    // vanity is selected, and the Web tab is hidden. We move the same DOM
    // nodes (not copies) so the input names — and the values they submit —
    // never change. Capture each field's home position ONCE so the other
    // modes restore it exactly where it was.
    var vanFields = [].slice.call(document.querySelectorAll('.puq-vanity-field'));
    var vanHome = vanFields.map(function (el) { return { el: el, parent: el.parentNode, next: el.nextSibling }; });
    var vanDest = document.getElementById('puq-vanity-extra');

    function applyDeploymentMode() {
        var unified = !!document.querySelector('#puq-rad-mode-unified:checked');
        var vanity  = !!document.querySelector('#puq-rad-mode-vanity:checked');
        var perRoleHidden = unified || vanity;

        var liAcct = document.getElementById('puq-tab-li-account');
        if (liAcct) liAcct.style.display = unified ? '' : 'none';
        var liVanity = document.getElementById('puq-tab-li-vanity');
        if (liVanity) liVanity.style.display = vanity ? '' : 'none';
        // Vanity hides the Mail + DNS limits tabs: the single mailbox is sized
        // on the Vanity tab (vanity_mail_quota) and there's no per-service DNS
        // zone to limit. Web limits stay (the vanity web user is a full account).
        var liMail = document.getElementById('puq-tab-li-mail');
        if (liMail) liMail.style.display = vanity ? 'none' : '';
        var liDns = document.getElementById('puq-tab-li-dns');
        if (liDns) liDns.style.display = vanity ? 'none' : '';
        // Vanity hides the whole Web limits tab — its still-relevant fields are
        // relocated onto the Vanity tab below.
        var liWeb = document.getElementById('puq-tab-li-web');
        if (liWeb) liWeb.style.display = vanity ? 'none' : '';

        // Move the marked fields into the Vanity tab (vanity) or back to their
        // original Web / Mail tab homes (split / unified).
        if (vanity && vanDest) {
            vanFields.forEach(function (el) { vanDest.appendChild(el); });
        } else {
            vanHome.forEach(function (h) {
                if (h.next && h.next.parentNode === h.parent) h.parent.insertBefore(h.el, h.next);
                else h.parent.appendChild(h.el);
            });
        }

        var splitOnly = document.querySelectorAll('.puq-split-only');
        for (var i = 0; i < splitOnly.length; i++) {
            splitOnly[i].style.display = perRoleHidden ? 'none' : '';
        }
        // If admin was sitting on a tab that just got hidden, fall back to General.
        var onHidden = (!unified && document.querySelector('#puq-tab-account.active'))
                    || (!vanity && document.querySelector('#puq-tab-vanity.active'))
                    || (vanity && document.querySelector('#puq-tab-mail.active'))
                    || (vanity && document.querySelector('#puq-tab-dns.active'))
                    || (vanity && document.querySelector('#puq-tab-web.active'));
        if (onHidden) {
            activateTab('#puq-tab-general');
        }
    }
    var modeRadios = document.querySelectorAll('input[name="packageconfigoption[6][deployment_mode]"]');
    for (var j = 0; j < modeRadios.length; j++) {
        modeRadios[j].addEventListener('change', applyDeploymentMode);
    }
    applyDeploymentMode();

    // ---- Config options auto-provisioner tab ----------------------------
    // Talks to the addon AJAX endpoints cross-page (same admin session, no
    // token needed — the dispatcher checks $_SESSION['adminid']). pid comes
    // from the configproducts.php URL (?id=N).
    (function initCfgOpts() {
        var listEl = document.getElementById('puq-cfgopts-list');
        if (!listEl || typeof jQuery === 'undefined') return;
        var $ = jQuery;
        var pid = parseInt((new URLSearchParams(window.location.search)).get('id') || '0', 10);
        var base = 'addonmodules.php?module=puq_web_hosting&ajax=';

        function esc(s) { var d = document.createElement('div'); d.textContent = (s == null ? '' : String(s)); return d.innerHTML; }

        function badge(o) {
            if (o.dynamic_empty) return '<span class="label label-default">no values yet</span>';
            if (!o.exists || o.present === 0) return '<span class="label label-danger">missing</span>';
            if (o.missing && o.missing.length > 0) return '<span class="label label-warning">partial ' + o.present + '/' + o.expected + '</span>';
            return '<span class="label label-success">complete ' + o.present + '/' + o.expected + '</span>';
        }

        function render(r) {
            var h = '<table class="table table-condensed" style="margin-top:6px;"><thead><tr>' +
                '<th>Option</th><th>Key</th><th>Source</th><th>Status</th><th>Default values</th></tr></thead><tbody>';
            (r.options || []).forEach(function (o) {
                h += '<tr><td>' + esc(o.name) + '</td><td><code>' + esc(o.key) + '</code></td><td>' + esc(o.source) +
                    '</td><td>' + badge(o) + '</td><td><small>' + (esc((o.values || []).join(', ')) || '—') + '</small></td></tr>';
            });
            h += '</tbody></table>';
            // Custom fields (the customer-entered name in vanity).
            if (r.custom_fields && r.custom_fields.length) {
                h += '<h5 style="margin-top:14px;">Custom fields <small class="text-muted">(customer enters at order)</small></h5>' +
                    '<table class="table table-condensed"><thead><tr><th>Field</th><th>Type</th><th>Status</th></tr></thead><tbody>';
                r.custom_fields.forEach(function (f) {
                    var b = f.exists ? '<span class="label label-success">present</span>' : '<span class="label label-danger">missing</span>';
                    h += '<tr><td><code>' + esc(f.fieldname) + '</code></td><td>' + esc(f.fieldtype) +
                        (f.required ? ' <span class="text-muted">(required)</span>' : '') + '</td><td>' + b + '</td></tr>';
                });
                h += '</tbody></table>';
            }
            listEl.innerHTML = h;
        }

        function load() {
            if (!pid) { listEl.innerHTML = '<div class="text-muted small">Save the product first, then reopen this tab.</div>'; return; }
            listEl.innerHTML = '<div class="text-muted small"><i class="fa fa-spinner fa-spin"></i> Loading…</div>';
            $.get(base + 'productConfigOptionsStatus&pid=' + pid, function (r) {
                if (!r || r.status !== 'success') { listEl.innerHTML = '<div class="text-danger">' + esc((r && r.msg) || 'Failed') + '</div>'; return; }
                render(r);
            }, 'json').fail(function () { listEl.innerHTML = '<div class="text-danger">Request failed.</div>'; });
        }

        $(document).on('click', '#puq-cfgopts-create', function () {
            if (!pid) { $('#puq-cfgopts-msg').css('color', '#a94442').text('Save the product first.'); return; }
            var b = this, t = b.innerHTML;
            b.disabled = true; b.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Working…';
            $('#puq-cfgopts-msg').text('');
            $.post(base + 'syncProductConfigOptions', { pid: pid }, function (r) {
                $('#puq-cfgopts-msg').css('color', (r && r.status === 'success') ? '#3c763d' : '#a94442').text((r && r.msg) || '');
                load();
            }, 'json').fail(function () {
                $('#puq-cfgopts-msg').css('color', '#a94442').text('Request failed.');
            }).always(function () { b.disabled = false; b.innerHTML = t; });
        });
        $(document).on('click', '#puq-cfgopts-refresh', load);
        // Lazy-load status the first time the tab is shown. Driven by our own
        // self-contained tab switcher (not Bootstrap's shown.bs.tab) so it
        // fires on every WHMCS version, including old admin themes.
        onTabShown('#puq-tab-cfgopts', function () {
            if (!listEl.getAttribute('data-loaded')) { listEl.setAttribute('data-loaded', '1'); load(); }
        });
    })();

    // ---- Email templates auto-provisioner tab ---------------------------
    // Same cross-page addon-AJAX pattern as the Config options tab. jQuery is
    // used (not the raw XHR helper) so the admin CSRF prefilter attaches the
    // X-PUQ-Token header — the email endpoints are state-changing writes.
    (function initEmailTpl() {
        var listEl = document.getElementById('puq-emailtpl-list');
        if (!listEl || typeof jQuery === 'undefined') return;
        var $ = jQuery;
        var pid = parseInt((new URLSearchParams(window.location.search)).get('id') || '0', 10);
        var base = 'addonmodules.php?module=puq_web_hosting&ajax=';

        function esc(s) { var d = document.createElement('div'); d.textContent = (s == null ? '' : String(s)); return d.innerHTML; }

        function statusBadge(o) {
            if (!o.exists) return '<span class="label label-danger">missing</span>';
            if (o.mapped && o.mapped !== o.name) return '<span class="label label-info">override</span>';
            return '<span class="label label-success">ready</span>';
        }

        function render(r) {
            var h = '<table class="table table-condensed" style="margin-top:6px;"><thead><tr>' +
                '<th>Event</th><th>Template</th><th>Status</th><th style="width:150px;">Actions</th></tr></thead><tbody>';
            (r.options || []).forEach(function (o) {
                var mappedNote = (o.mapped && o.mapped !== o.name)
                    ? '<div class="text-muted"><small>override: <code>' + esc(o.mapped) + '</code></small></div>' : '';
                h += '<tr>' +
                    '<td><code>' + esc(o.event) + '</code></td>' +
                    '<td>' + esc(o.name) + mappedNote + '</td>' +
                    '<td>' + statusBadge(o) + '</td>' +
                    '<td>' +
                        (o.exists
                            ? '<button type="button" class="btn btn-xs btn-warning puq-emailtpl-row" data-mode="overwrite" data-event="' + esc(o.event) + '"><i class="fa fa-undo"></i> Reset</button>'
                            : '<button type="button" class="btn btn-xs btn-success puq-emailtpl-row" data-mode="missing" data-event="' + esc(o.event) + '"><i class="fa fa-plus"></i> Create</button>') +
                    '</td>' +
                    '</tr>';
            });
            h += '</tbody></table>';
            listEl.innerHTML = h;
        }

        function load() {
            if (!pid) { listEl.innerHTML = '<div class="text-muted small">Save the product first, then reopen this tab.</div>'; return; }
            listEl.innerHTML = '<div class="text-muted small"><i class="fa fa-spinner fa-spin"></i> Loading…</div>';
            $.get(base + 'emailTemplatesStatus&pid=' + pid, function (r) {
                if (!r || r.status !== 'success') { listEl.innerHTML = '<div class="text-danger">' + esc((r && r.msg) || 'Failed') + '</div>'; return; }
                render(r);
            }, 'json').fail(function () { listEl.innerHTML = '<div class="text-danger">Request failed.</div>'; });
        }

        // Run a sync (mode = missing|overwrite, event = '' for all). $btn is the
        // clicked button to disable/spin during the request.
        function runSync(mode, event, $btn, confirmMsg) {
            if (!pid) { $('#puq-emailtpl-msg').css('color', '#a94442').text('Save the product first.'); return; }
            if (confirmMsg && !window.confirm(confirmMsg)) return;
            var orig = $btn ? $btn.html() : '';
            if ($btn) { $btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i>'); }
            $('#puq-emailtpl-msg').text('');
            $.post(base + 'syncEmailTemplates', { pid: pid, mode: mode, event: event || '' }, function (r) {
                $('#puq-emailtpl-msg').css('color', (r && r.status === 'success') ? '#3c763d' : '#a94442').text((r && r.msg) || '');
                load();
            }, 'json').fail(function () {
                $('#puq-emailtpl-msg').css('color', '#a94442').text('Request failed.');
            }).always(function () { if ($btn) { $btn.prop('disabled', false).html(orig); } });
        }

        $(document).on('click', '#puq-emailtpl-create-all', function () { runSync('missing', '', $(this)); });
        $(document).on('click', '#puq-emailtpl-reset-all', function () {
            runSync('overwrite', '', $(this), 'Reset ALL email templates back to the module defaults? Any edits you made to these templates will be overwritten.');
        });
        $(document).on('click', '#puq-emailtpl-refresh', load);
        $(document).on('click', '.puq-emailtpl-row', function () {
            var mode = this.getAttribute('data-mode');
            var event = this.getAttribute('data-event');
            var msg = mode === 'overwrite'
                ? 'Reset this template back to the module default? Your edits to it will be overwritten.'
                : null;
            runSync(mode, event, $(this), msg);
        });

        onTabShown('#puq-tab-emailtpl', function () {
            if (!listEl.getAttribute('data-loaded')) { listEl.setAttribute('data-loaded', '1'); load(); }
        });
    })();
})();
