/**
 * AI Visibility Tracker — dashboard card behavior.
 *
 * Runs on-demand checks (Refresh / Run first check), emails the report, and
 * edits the tracked-prompt list against the three AJAX actions
 * (sitestaffr_visibility_check_now / _send_report / _update_prompts).
 *
 * SECURITY: every value that can originate from the AJAX `run` payload or a
 * prompt the owner typed (prompt text, competitor domains, platform keys) is
 * rendered via `textContent` / DOM properties only — never `.html()` /
 * `innerHTML`. See admin/views/admin-blog-agent.php for the matching
 * server-rendered markup this mirrors (the two must stay in sync).
 *
 * The run + email buttons are bound by DELEGATION on the card, because
 * renderRun() rebuilds the summary band (and its buttons) after each check.
 *
 * @package    SiteStaffr
 * @subpackage SiteStaffr/admin/js
 * @since      1.36.0
 */
(function ($) {
    'use strict';

    var data = window.sitestaffrVisibilityData || {};
    var i18n = data.i18n || {};
    var platformLabels = data.platforms || {};
    var PROVIDERS = ['perplexity', 'chatgpt', 'gemini'];

    function el(tag, opts) {
        var node = document.createElement(tag);
        opts = opts || {};
        if (opts.className) {
            node.className = opts.className;
        }
        if (typeof opts.text !== 'undefined') {
            node.textContent = opts.text;
        }
        if (opts.attrs) {
            Object.keys(opts.attrs).forEach(function (key) {
                node.setAttribute(key, opts.attrs[key]);
            });
        }
        return node;
    }

    function clear(node) {
        while (node && node.firstChild) {
            node.removeChild(node.firstChild);
        }
    }

    function notify(message) {
        if (window.SiteStaffrModal) {
            window.SiteStaffrModal.alertDialog({ message: message });
        }
    }

    function platformLabel(key) {
        return platformLabels[key] || key;
    }

    function formatRunDate(iso) {
        if (!iso) {
            return '';
        }
        var parsed = new Date(iso);
        if (isNaN(parsed.getTime())) {
            return '';
        }
        return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });
    }

    // ---- Result rendering: summary band + two-column data area ----

    function buildTrend(cited, prevCited) {
        if (prevCited === null || typeof prevCited === 'undefined') {
            return null;
        }
        var delta = cited - prevCited;
        var cls, text;
        if (delta > 0) {
            cls = 'is-up';
            text = '▲ ' + (i18n.up || 'Up') + ' ' + delta;
        } else if (delta < 0) {
            cls = 'is-down';
            text = '▼ ' + (i18n.down || 'Down') + ' ' + Math.abs(delta);
        } else {
            cls = 'is-flat';
            text = '— ' + (i18n.noChange || 'No change');
        }
        return el('span', { className: 'sitestaffr-visibility-trend ' + cls, text: text });
    }

    function buildRunButton(rateLimit) {
        var btn = document.createElement('button');
        btn.type = 'button';
        btn.className = 'button sitestaffr-visibility-run';
        var icon = document.createElement('span');
        icon.className = 'dashicons dashicons-update';
        icon.setAttribute('aria-hidden', 'true');
        btn.appendChild(icon);
        btn.appendChild(document.createTextNode(' ' + (i18n.refresh || 'Refresh')));
        if (rateLimit && typeof rateLimit.remaining_on_demand !== 'undefined') {
            var rem = Math.max(0, parseInt(rateLimit.remaining_on_demand, 10) || 0);
            var tmpl = (rem === 1)
                ? (i18n.remainingOne || '%d on-demand check left this month')
                : (i18n.remainingOther || '%d on-demand checks left this month');
            btn.title = tmpl.replace('%d', String(rem));
            btn.disabled = (rem === 0);
        }
        return btn;
    }

    function buildEmailButton() {
        var btn = document.createElement('button');
        btn.type = 'button';
        btn.className = 'button sitestaffr-visibility-email';
        var icon = document.createElement('span');
        icon.className = 'dashicons dashicons-email-alt';
        icon.setAttribute('aria-hidden', 'true');
        btn.appendChild(icon);
        btn.appendChild(document.createTextNode(' ' + (i18n.emailReport || 'Email report')));
        return btn;
    }

    function buildSummary(run, cited, total, prevCited, rateLimit) {
        var band = el('div', { className: 'sitestaffr-visibility-summary' });

        // Score cluster.
        var score = el('div', { className: 'sitestaffr-visibility-score' });
        var top = el('div', { className: 'sitestaffr-visibility-score-top' });
        var num = el('span', { className: 'sitestaffr-visibility-num' });
        var b = document.createElement('b');
        b.textContent = String(cited);
        num.appendChild(b);
        num.appendChild(el('span', { className: 'den', text: '/ ' + total }));
        top.appendChild(num);
        var trend = buildTrend(cited, prevCited);
        if (trend) {
            top.appendChild(trend);
        }
        score.appendChild(top);
        score.appendChild(el('span', { className: 'sitestaffr-visibility-score-lab', text: i18n.aiAnswersCiteYou || 'AI answers cite you' }));
        band.appendChild(score);

        band.appendChild(el('div', { className: 'sitestaffr-visibility-vr', attrs: { 'aria-hidden': 'true' } }));

        // Per-engine breakdown.
        var engines = el('div', { className: 'sitestaffr-visibility-engines' });
        var byPlatform = (run.byPlatform && typeof run.byPlatform === 'object') ? run.byPlatform : {};
        PROVIDERS.forEach(function (key) {
            var p = (byPlatform[key] && typeof byPlatform[key] === 'object') ? byPlatform[key] : {};
            var eng = el('div', { className: 'sitestaffr-visibility-eng' });
            eng.appendChild(el('span', { className: 'k', text: platformLabel(key) }));
            if (p.available) {
                var pc = parseInt(p.cited, 10) || 0;
                var pt = parseInt(p.total, 10) || 0;
                eng.appendChild(el('span', { className: 'v', text: pc + '/' + pt }));
            } else {
                eng.appendChild(el('span', { className: 'v na', text: '—', attrs: { title: i18n.unavailableTitle || 'Unavailable for this check' } }));
            }
            engines.appendChild(eng);
        });
        band.appendChild(engines);

        // Meta + actions.
        var right = el('div', { className: 'sitestaffr-visibility-summary-right' });
        var dateText = formatRunDate(run.date);
        if (dateText) {
            right.appendChild(el('span', { className: 'sitestaffr-visibility-meta', text: (i18n.checked || 'Checked %s').replace('%s', dateText) }));
        }
        var actions = el('div', { className: 'sitestaffr-visibility-actions' });
        actions.appendChild(buildRunButton(rateLimit));
        actions.appendChild(buildEmailButton());
        right.appendChild(actions);
        right.appendChild(el('span', { className: 'sitestaffr-visibility-status', attrs: { 'aria-live': 'polite' } }));
        band.appendChild(right);

        return band;
    }

    function buildByPrompt(prompts) {
        var wrap = el('div', { className: 'sitestaffr-visibility-byprompt' });

        var citedCount = 0;
        prompts.forEach(function (p) { if (p && p.cited) { citedCount++; } });
        var missedCount = Math.max(0, prompts.length - citedCount);

        var h = el('div', { className: 'sitestaffr-visibility-block-h' });
        h.appendChild(el('h3', { text: i18n.byPrompt || 'By prompt' }));
        var metaTmpl = i18n.citedMissed || '%1$d cited · %2$d missed';
        h.appendChild(el('span', { className: 'meta', text: metaTmpl.replace('%1$d', String(citedCount)).replace('%2$d', String(missedCount)) }));
        wrap.appendChild(h);

        var table = el('table', { className: 'sitestaffr-visibility-tbl' });
        var thead = document.createElement('thead');
        var htr = document.createElement('tr');
        htr.appendChild(el('th', { className: 'c-q', text: i18n.prompt || 'Prompt' }));
        htr.appendChild(el('th', { className: 'c-res', text: i18n.result || 'Result' }));
        thead.appendChild(htr);
        table.appendChild(thead);

        var tbody = document.createElement('tbody');
        prompts.forEach(function (p) {
            if (!p || typeof p !== 'object') {
                return;
            }
            var cited = !!p.cited;
            var tr = el('tr', { className: cited ? 'tr-cited' : 'tr-miss' });

            var qtd = el('td', { className: 'c-q' });
            var qcell = el('span', { className: 'q-cell' });
            qcell.appendChild(el('span', { className: 'mk', text: cited ? '✓' : '✗', attrs: { 'aria-hidden': 'true' } }));
            qcell.appendChild(el('span', { className: 'q-text', text: String(p.text || '') }));
            qtd.appendChild(qcell);
            tr.appendChild(qtd);

            var rtd = el('td', { className: 'c-res' });
            if (cited) {
                var citedOn = Array.isArray(p.citedOn) ? p.citedOn.map(platformLabel) : [];
                rtd.appendChild(el('span', { className: 'res-ok', text: citedOn.length ? citedOn.join(', ') : (i18n.citedLabel || 'cited') }));
            } else {
                var span = el('span', { className: 'res-no' });
                var strong = document.createElement('b');
                strong.textContent = i18n.notCitedLabel || 'not cited';
                span.appendChild(strong);
                var comps = Array.isArray(p.competitors) ? p.competitors : [];
                if (comps.length) {
                    span.appendChild(document.createTextNode(' · ' + comps.join(', ')));
                }
                rtd.appendChild(span);
            }
            tr.appendChild(rtd);
            tbody.appendChild(tr);
        });
        table.appendChild(tbody);
        wrap.appendChild(table);
        return wrap;
    }

    function buildRail(aggregate) {
        var wrap = el('div', { className: 'sitestaffr-visibility-competitors' });
        var rail = el('div', { className: 'sitestaffr-visibility-rail' });
        var h = el('div', { className: 'sitestaffr-visibility-block-h' });
        h.appendChild(el('h3', { text: i18n.whosBeatingYou || "Who's beating you" }));
        rail.appendChild(h);

        var ul = el('ul', { className: 'sitestaffr-visibility-rank' });
        aggregate.forEach(function (row) {
            if (!row || typeof row !== 'object' || !row.domain) {
                return;
            }
            var count = parseInt(row.count, 10) || 0;
            var li = document.createElement('li');
            li.appendChild(el('span', { className: 'd', text: String(row.domain) }));
            var tmpl = (count === 1)
                ? (i18n.citedOnMissedOne || 'cited on 1 missed question')
                : (i18n.citedOnMissedOther || 'cited on %d missed questions');
            li.appendChild(el('span', { className: 'c', text: String(count), attrs: { title: tmpl.replace('%d', String(count)) } }));
            ul.appendChild(li);
        });
        rail.appendChild(ul);
        wrap.appendChild(rail);
        return wrap;
    }

    function buildGrid(run) {
        var prompts = Array.isArray(run.prompts) ? run.prompts : [];
        var aggregate = Array.isArray(run.competitorsAggregate) ? run.competitorsAggregate : [];
        var hasRail = aggregate.length > 0;

        var grid = el('div', { className: 'sitestaffr-visibility-grid' + (hasRail ? '' : ' is-single') });
        grid.appendChild(buildByPrompt(prompts));
        if (hasRail) {
            grid.appendChild(buildRail(aggregate));
        }
        return grid;
    }

    function renderRun(run) {
        run = (run && typeof run === 'object') ? run : {};
        var wrapEl = document.getElementById('sitestaffr-visibility-results');
        if (!wrapEl) {
            return;
        }

        var prevAttr = wrapEl.getAttribute('data-score-cited');
        var prevCited = (prevAttr !== null && prevAttr !== '') ? parseInt(prevAttr, 10) : null;

        var score = (run.score && typeof run.score === 'object') ? run.score : {};
        var cited = parseInt(score.cited, 10) || 0;
        var total = parseInt(score.total, 10) || 0;

        clear(wrapEl);
        wrapEl.appendChild(buildSummary(run, cited, total, prevCited, run.rate_limit));
        wrapEl.appendChild(buildGrid(run));

        wrapEl.setAttribute('data-score-cited', String(cited));
        wrapEl.hidden = false;

        var emptyEl = document.getElementById('sitestaffr-visibility-empty');
        if (emptyEl) {
            emptyEl.hidden = true;
        }
    }

    // ---- On-demand check (Refresh / Run first check) — delegated ----

    function runStatusFor($btn) {
        return $btn.closest('.sitestaffr-visibility-summary-right, .sitestaffr-visibility-empty-actions')
            .find('.sitestaffr-visibility-status').first();
    }

    function initRun($card) {
        $card.on('click', '.sitestaffr-visibility-run', function () {
            var $btn = $(this);
            if ($btn.prop('disabled')) {
                return;
            }
            var $status = runStatusFor($btn);

            $btn.prop('disabled', true);
            $status.text(i18n.checking || 'Checking...').css('color', '');

            $.post(data.ajaxurl, {
                action: 'sitestaffr_visibility_check_now',
                nonce: data.nonce
            }, function (response) {
                if (response && response.success && response.data) {
                    // renderRun rebuilds the band (fresh buttons/state) and hides the empty state.
                    renderRun(response.data.run);
                } else {
                    var respData = (response && response.data) || {};
                    $status.text(respData.message || i18n.checkFailed || 'Visibility check failed.').css('color', '#991b1b');
                    // A rate-limited response means remaining is genuinely 0 — stay disabled.
                    if (respData.code !== 'rate_limited') {
                        $btn.prop('disabled', false);
                    }
                }
            }).fail(function () {
                $status.text(i18n.checkFailed || 'Visibility check failed.').css('color', '#991b1b');
                $btn.prop('disabled', false);
            });
        });
    }

    // ---- Email this report — delegated ----

    function initEmailReport($card) {
        $card.on('click', '.sitestaffr-visibility-email', function () {
            var $btn = $(this);
            if ($btn.prop('disabled')) {
                return;
            }
            var $status = $btn.closest('.sitestaffr-visibility-summary-right').find('.sitestaffr-visibility-status').first();

            $btn.prop('disabled', true);
            $status.text(i18n.sendingReport || 'Sending...').css('color', '');

            $.post(data.ajaxurl, {
                action: 'sitestaffr_visibility_send_report',
                nonce: data.nonce
            }, function (response) {
                if (response && response.success) {
                    $status.text(i18n.reportSent || 'Sent to your inbox.').css('color', '#10b981');
                    setTimeout(function () { $status.text(''); }, 4000);
                } else {
                    var respData = (response && response.data) || {};
                    $status.text(respData.message || i18n.reportFailed || 'Could not send the report.').css('color', '#991b1b');
                }
                $btn.prop('disabled', false);
            }).fail(function () {
                $status.text(i18n.reportFailed || 'Could not send the report.').css('color', '#991b1b');
                $btn.prop('disabled', false);
            });
        });
    }

    // ---- Editable prompt list ----

    function buildPromptRow(prompt) {
        prompt = prompt || {};
        var li = document.createElement('li');
        li.className = 'sitestaffr-visibility-prompt-row';
        li.setAttribute('data-id', String(prompt.id || ''));

        var input = document.createElement('input');
        input.type = 'text';
        input.className = 'regular-text sitestaffr-visibility-prompt-input';
        input.maxLength = 200;
        input.value = String(prompt.text || '');
        input.setAttribute('aria-label', i18n.promptTextLabel || 'Prompt text');
        li.appendChild(input);

        var select = document.createElement('select');
        select.className = 'sitestaffr-visibility-prompt-type';
        select.setAttribute('aria-label', i18n.promptTypeLabel || 'Prompt type');

        var brandedOption = document.createElement('option');
        brandedOption.value = 'branded';
        brandedOption.textContent = i18n.brandedLabel || 'Branded';
        select.appendChild(brandedOption);

        var unbrandedOption = document.createElement('option');
        unbrandedOption.value = 'unbranded';
        unbrandedOption.textContent = i18n.unbrandedLabel || 'Local/Unbranded';
        select.appendChild(unbrandedOption);

        select.value = (prompt.type === 'unbranded') ? 'unbranded' : 'branded';
        li.appendChild(select);

        var deleteBtn = document.createElement('button');
        deleteBtn.type = 'button';
        deleteBtn.className = 'button button-small button-link-delete sitestaffr-visibility-prompt-delete';
        deleteBtn.setAttribute('aria-label', i18n.deletePrompt || 'Delete prompt');
        var trashIcon = document.createElement('span');
        trashIcon.className = 'dashicons dashicons-trash';
        trashIcon.setAttribute('aria-hidden', 'true');
        deleteBtn.appendChild(trashIcon);
        li.appendChild(deleteBtn);

        return li;
    }

    function renderPromptsList(prompts) {
        var $list = $('#sitestaffr-visibility-prompts-list');
        var listEl = $list[0];
        if (!listEl) {
            return;
        }
        clear(listEl);
        (prompts || []).forEach(function (prompt) {
            listEl.appendChild(buildPromptRow(prompt));
        });
    }

    function initPromptsAdd() {
        $('#sitestaffr-visibility-prompts-add').on('click', function () {
            var $list = $('#sitestaffr-visibility-prompts-list');
            var listEl = $list[0];
            if (!listEl) {
                return;
            }
            var max = parseInt($list.attr('data-max'), 10) || 10;
            if (listEl.children.length >= max) {
                notify(i18n.maxPrompts || 'You can track up to 10 prompts.');
                return;
            }
            var row = buildPromptRow({ id: '', text: '', type: 'branded' });
            listEl.appendChild(row);
            $(row).find('.sitestaffr-visibility-prompt-input').trigger('focus');
        });
    }

    function initPromptsDelete() {
        $('#sitestaffr-visibility-prompts-list').on('click', '.sitestaffr-visibility-prompt-delete', function () {
            $(this).closest('li').remove();
        });
    }

    function initPromptsSave() {
        $('#sitestaffr-visibility-prompts-save').on('click', function () {
            var $btn = $(this);
            var $status = $('#sitestaffr-visibility-prompts-status');
            if ($btn.prop('disabled')) {
                return;
            }

            var prompts = [];
            $('#sitestaffr-visibility-prompts-list > li').each(function () {
                var $row = $(this);
                var text = $.trim($row.find('.sitestaffr-visibility-prompt-input').val() || '');
                if (!text) {
                    return;
                }
                var type = $row.find('.sitestaffr-visibility-prompt-type').val();
                prompts.push({
                    id: $row.attr('data-id') || '',
                    text: text,
                    type: (type === 'unbranded') ? 'unbranded' : 'branded'
                });
            });

            $btn.prop('disabled', true);
            $status.text(i18n.saving || 'Saving...').css('color', '#666');

            $.post(data.ajaxurl, {
                action: 'sitestaffr_visibility_update_prompts',
                nonce: data.nonce,
                prompts: prompts
            }, function (response) {
                $btn.prop('disabled', false);
                if (response && response.success && response.data) {
                    renderPromptsList(response.data.prompts || prompts);
                    $status.text(i18n.saved || 'Saved!').css('color', '#10b981');
                    setTimeout(function () { $status.text(''); }, 2000);
                } else {
                    var respData = (response && response.data) || {};
                    $status.text(respData.message || i18n.saveFailed || 'Save failed.').css('color', '#991b1b');
                }
            }).fail(function () {
                $btn.prop('disabled', false);
                $status.text(i18n.saveFailed || 'Save failed.').css('color', '#991b1b');
            });
        });
    }

    // ---- Suggest prompts (gap-aware) ----

    function renderSuggestions(suggestions) {
        var panelEl = document.getElementById('sitestaffr-visibility-suggestions');
        var listEl = document.getElementById('sitestaffr-visibility-suggestions-list');
        if (!panelEl || !listEl) {
            return;
        }
        clear(listEl);
        (suggestions || []).forEach(function (s) {
            if (!s || !s.text) {
                return;
            }
            var li = document.createElement('li');
            li.className = 'sitestaffr-visibility-suggestion';
            li.setAttribute('data-id', String(s.id || ''));
            li.setAttribute('data-text', String(s.text));
            li.setAttribute('data-type', s.type === 'unbranded' ? 'unbranded' : 'branded');

            var textWrap = el('span', { className: 'sitestaffr-visibility-suggestion-text' });
            textWrap.appendChild(el('span', { className: 'q', text: String(s.text) }));
            var typeLabel = (s.type === 'unbranded') ? (i18n.unbrandedLabel || 'Local/Unbranded') : (i18n.brandedLabel || 'Branded');
            textWrap.appendChild(el('span', { className: 'sitestaffr-visibility-suggestion-type', text: typeLabel }));
            li.appendChild(textWrap);

            var addBtn = document.createElement('button');
            addBtn.type = 'button';
            addBtn.className = 'button button-small sitestaffr-visibility-suggestion-add';
            addBtn.textContent = i18n.add || 'Add';
            li.appendChild(addBtn);

            listEl.appendChild(li);
        });
        panelEl.hidden = listEl.children.length === 0;
    }

    function initPromptsSuggest() {
        var $btn = $('#sitestaffr-visibility-prompts-suggest');
        var $status = $('#sitestaffr-visibility-prompts-status');
        if (!$btn.length) {
            return;
        }

        $btn.on('click', function () {
            if ($btn.prop('disabled')) {
                return;
            }
            $btn.prop('disabled', true);
            $status.text(i18n.suggesting || 'Finding suggestions...').css('color', '#666');

            $.post(data.ajaxurl, {
                action: 'sitestaffr_visibility_suggest_prompts',
                nonce: data.nonce
            }, function (response) {
                $btn.prop('disabled', false);
                if (response && response.success && response.data && Array.isArray(response.data.prompts)) {
                    if (!response.data.prompts.length) {
                        $status.text(i18n.noSuggestions || 'No new suggestions right now.').css('color', '#646970');
                        var emptyPanel = document.getElementById('sitestaffr-visibility-suggestions');
                        if (emptyPanel) { emptyPanel.hidden = true; }
                        return;
                    }
                    $status.text('');
                    renderSuggestions(response.data.prompts);
                } else {
                    var respData = (response && response.data) || {};
                    $status.text(respData.message || i18n.suggestFailed || "Couldn't get suggestions.").css('color', '#991b1b');
                }
            }).fail(function () {
                $btn.prop('disabled', false);
                $status.text(i18n.suggestFailed || "Couldn't get suggestions.").css('color', '#991b1b');
            });
        });

        // Delegated: add a suggestion to the editable list (respecting the cap).
        $('#sitestaffr-visibility-suggestions-list').on('click', '.sitestaffr-visibility-suggestion-add', function () {
            var $li = $(this).closest('li');
            var $list = $('#sitestaffr-visibility-prompts-list');
            var listEl = $list[0];
            if (!listEl) {
                return;
            }
            var max = parseInt($list.attr('data-max'), 10) || 10;
            if (listEl.children.length >= max) {
                notify(i18n.maxPrompts || 'You can track up to 10 prompts.');
                return;
            }
            listEl.appendChild(buildPromptRow({
                id: $li.attr('data-id') || '',
                text: $li.attr('data-text') || '',
                type: $li.attr('data-type') || 'branded'
            }));
            $li.remove();
            $status.text(i18n.unsavedPrompts || 'Save prompts to keep your changes.').css('color', '#646970');

            var listNode = document.getElementById('sitestaffr-visibility-suggestions-list');
            var panelNode = document.getElementById('sitestaffr-visibility-suggestions');
            if (panelNode && listNode && listNode.children.length === 0) {
                panelNode.hidden = true;
            }
        });
    }

    $(document).ready(function () {
        var $card = $('#sitestaffr-visibility-card');
        if (!$card.length) {
            return;
        }
        initRun($card);
        initEmailReport($card);
        initPromptsAdd();
        initPromptsDelete();
        initPromptsSave();
        initPromptsSuggest();
    });
})(jQuery);
