<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ -- NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/templates/competitor-gap.php
// Description: Competitor Gap tab -- analyze competitor URLs, save them, re-analyze all, queue gap topics for blog generator - NUCLEAR+++
// Last Edited: 2026-05-18
// ==================================================
defined('ABSPATH') || exit;

$saved       = \AutoMarketerAI\CompetitorGap::getSavedCompetitors();
$queued      = \AutoMarketerAI\GapTopicQueue::getAll();
$queue_count = count($queued);
$queue_full  = $queue_count >= \AutoMarketerAI\GapTopicQueue::MAX_QUEUE;
?>
<div class="amai-gap-wrap" id="amai-gap-wrap">

    <div class="amai-gap-intro-card">
        <div class="amai-gap-intro-icon">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#D97757" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></svg>
        </div>
        <div class="amai-gap-intro-text">
            <strong>Find topics your competitors cover that you don't.</strong>
            Paste a competitor's blog page URL below. We'll analyze it and suggest blog posts that fill the gaps in your content. Queue a topic and it will be used automatically in your next Monday, Wednesday, or Friday blog post.
        </div>
    </div>

    <?php
    // Blog queue section -- always rendered, hidden via CSS when empty
    $queue_hidden_attr = $queue_count === 0 ? ' style="display:none;"' : '';
    ?>
    <div class="amai-gap-queue-card" id="amai-gap-queue-card"<?php echo $queue_hidden_attr; ?>>
        <div class="amai-gap-queue-header">
            <div class="amai-gap-queue-title-row">
                <strong>Blog post queue</strong>
                <span class="amai-gap-queue-badge" id="amai-gap-queue-badge"><?php echo $queue_count; ?> of <?php echo \AutoMarketerAI\GapTopicQueue::MAX_QUEUE; ?></span>
            </div>
            <p class="amai-gap-queue-desc">These topics will be used automatically on your next Mon/Wed/Fri blog post days, oldest first.</p>
        </div>
        <div class="amai-gap-queue-list" id="amai-gap-queue-list">
            <?php foreach ($queued as $item) : ?>
            <div class="amai-gap-queue-row<?php echo $item['is_stale'] ? ' amai-gap-queue-row--stale' : ''; ?>" id="amai-gap-qrow-<?php echo (int) $item['id']; ?>">
                <div class="amai-gap-queue-row-text">
                    <span class="amai-gap-queue-topic"><?php echo esc_html($item['topic']); ?></span>
                    <?php if ($item['days_ago'] > 0) : ?>
                    <span class="amai-gap-queue-age<?php echo $item['is_stale'] ? ' amai-gap-queue-age--stale' : ''; ?>">
                        <?php if ($item['is_stale']) : ?>
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
                        <?php endif; ?>
                        <?php echo (int) $item['days_ago']; ?>d ago
                    </span>
                    <?php endif; ?>
                </div>
                <button type="button" class="amai-gap-queue-remove" data-id="<?php echo (int) $item['id']; ?>" title="Remove from queue">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                </button>
            </div>
            <?php endforeach; ?>
        </div>
        <?php if ($queue_full) : ?>
        <p class="amai-gap-queue-full-msg" id="amai-gap-queue-full-msg">Queue is full. Remove a topic or wait for the blog generator to use one before adding more.</p>
        <?php else : ?>
        <p class="amai-gap-queue-full-msg" id="amai-gap-queue-full-msg" style="display:none;">Queue is full. Remove a topic or wait for the blog generator to use one before adding more.</p>
        <?php endif; ?>
    </div>

    <div class="amai-gap-form-card">
        <label class="amai-gap-label" for="amai-gap-url">Analyze a competitor page</label>
        <div class="amai-gap-input-row">
            <input
                type="url"
                id="amai-gap-url"
                class="amai-gap-url-input"
                placeholder="https://competitor.com/blog"
                autocomplete="off"
            />
            <button type="button" id="amai-gap-analyze-btn" class="amai-gap-btn-primary">
                <span class="amai-gap-btn-label">Analyze</span>
                <span class="amai-gap-btn-spinner" style="display:none;">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>
                </span>
            </button>
        </div>
        <div id="amai-gap-error" class="amai-gap-error" style="display:none;"></div>
        <div id="amai-gap-save-row" class="amai-gap-save-row" style="display:none;">
            <span class="amai-gap-save-label">Save this competitor so you can re-analyze it later?</span>
            <button type="button" id="amai-gap-save-btn" class="amai-gap-btn-secondary">Save competitor</button>
        </div>
    </div>

    <?php if (!empty($saved)) : ?>
    <div class="amai-gap-saved-card" id="amai-gap-saved-card">
    <?php else : ?>
    <div class="amai-gap-saved-card" id="amai-gap-saved-card" style="display:none;">
    <?php endif; ?>
        <div class="amai-gap-saved-header">
            <strong>Saved competitors</strong>
            <button type="button" id="amai-gap-reanalyze-btn" class="amai-gap-btn-primary amai-gap-btn-sm"<?php echo empty($saved) ? ' style="display:none;"' : ''; ?>>
                <span class="amai-gap-btn-label">Re-analyze all</span>
                <span class="amai-gap-btn-spinner" style="display:none;">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>
                </span>
            </button>
        </div>
        <div class="amai-gap-saved-list" id="amai-gap-saved-list">
            <?php foreach ($saved as $competitor) : ?>
            <div class="amai-gap-saved-row" id="amai-gap-saved-<?php echo (int) $competitor->id; ?>">
                <div class="amai-gap-saved-info">
                    <span class="amai-gap-saved-name"><?php echo esc_html($competitor->label); ?></span>
                    <span class="amai-gap-saved-url"><?php echo esc_html($competitor->url); ?></span>
                </div>
                <div class="amai-gap-saved-actions">
                    <?php if ($competitor->last_analyzed_at) : ?>
                    <span class="amai-gap-saved-last">Last analyzed <?php echo esc_html(date('M j', strtotime((string) $competitor->last_analyzed_at))); ?></span>
                    <?php endif; ?>
                    <button type="button" class="amai-gap-btn-analyze-saved" data-url="<?php echo esc_attr($competitor->url); ?>">Analyze</button>
                    <button type="button" class="amai-gap-btn-delete" data-id="<?php echo (int) $competitor->id; ?>" title="Remove">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                    </button>
                </div>
            </div>
            <?php endforeach; ?>
        </div>
    </div>

    <div id="amai-gap-results" class="amai-gap-results" style="display:none;">
        <div class="amai-gap-results-header">
            <strong id="amai-gap-results-title">Content gaps found</strong>
        </div>
        <div id="amai-gap-list" class="amai-gap-list"></div>
    </div>

</div>

<div class="amai-reviews-wrap" id="amai-reviews-wrap">

    <div class="amai-gap-intro-card">
        <div class="amai-gap-intro-icon">
            <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" stroke="#D97757" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
        </div>
        <div class="amai-gap-intro-text">
            <strong>Competitor review mining</strong>
            Enter a competitor's domain below. We'll analyze common complaints in their reviews and turn each one into a blog post opportunity that positions you as the better choice.
        </div>
    </div>

    <div class="amai-gap-form-card">
        <label class="amai-gap-label" for="amai-rv-domain">Competitor domain</label>
        <div class="amai-gap-input-row">
            <input type="text" id="amai-rv-domain" class="amai-gap-url-input" placeholder="e.g. competitorname.com" autocomplete="off" />
            <button type="button" id="amai-rv-analyze-btn" class="amai-gap-btn-primary">
                <span class="amai-gap-btn-label">Find opportunities</span>
                <span class="amai-gap-btn-spinner" style="display:none;"></span>
            </button>
        </div>
        <div id="amai-rv-error" class="amai-gap-error" style="display:none;"></div>
    </div>

    <div id="amai-rv-results" class="amai-gap-results" style="display:none;">
        <div class="amai-gap-results-header">
            <strong id="amai-rv-results-title">Opportunities found</strong>
        </div>
        <div id="amai-rv-list" class="amai-gap-list"></div>
    </div>

</div>

<script>
(function() {
    var nonce        = <?php echo wp_json_encode(wp_create_nonce('amai_competitor_gap')); ?>;
    var ajaxurl      = <?php echo wp_json_encode(admin_url('admin-ajax.php')); ?>;
    var maxQueue     = <?php echo (int) \AutoMarketerAI\GapTopicQueue::MAX_QUEUE; ?>;
    var currentUrl   = '';
    var queueCount   = <?php echo $queue_count; ?>;

    var urlInput      = document.getElementById('amai-gap-url');
    var analyzeBtn    = document.getElementById('amai-gap-analyze-btn');
    var errorBox      = document.getElementById('amai-gap-error');
    var saveRow       = document.getElementById('amai-gap-save-row');
    var saveBtn       = document.getElementById('amai-gap-save-btn');
    var resultsWrap   = document.getElementById('amai-gap-results');
    var resultsTitle  = document.getElementById('amai-gap-results-title');
    var gapList       = document.getElementById('amai-gap-list');
    var savedCard     = document.getElementById('amai-gap-saved-card');
    var savedList     = document.getElementById('amai-gap-saved-list');
    var reanalyzeBtn  = document.getElementById('amai-gap-reanalyze-btn');
    var queueCard     = document.getElementById('amai-gap-queue-card');
    var queueList     = document.getElementById('amai-gap-queue-list');
    var queueBadge    = document.getElementById('amai-gap-queue-badge');
    var queueFullMsg  = document.getElementById('amai-gap-queue-full-msg');

    function setLoading(btn, on) {
        btn.disabled = on;
        var label   = btn.querySelector('.amai-gap-btn-label');
        var spinner = btn.querySelector('.amai-gap-btn-spinner');
        if (label)   label.style.display   = on ? 'none' : '';
        if (spinner) spinner.style.display = on ? 'inline-flex' : 'none';
    }

    function showError(msg) {
        errorBox.textContent   = msg;
        errorBox.style.display = 'block';
    }

    function hideError() {
        errorBox.style.display = 'none';
        errorBox.textContent   = '';
    }

    function updateQueueState(count, full) {
        queueCount = count;
        queueBadge.textContent = count + ' of ' + maxQueue;
        queueFullMsg.style.display = full ? 'block' : 'none';
        if (count > 0) {
            queueCard.style.display = 'block';
        }
        // Update all queue buttons in the results list
        gapList.querySelectorAll('.amai-gap-btn-queue').forEach(function(btn) {
            if (full) {
                btn.disabled = true;
                if (!btn.classList.contains('amai-gap-btn-queued')) {
                    btn.textContent = 'Queue full';
                }
            } else {
                if (!btn.classList.contains('amai-gap-btn-queued')) {
                    btn.disabled = false;
                    btn.textContent = 'Queue for Blog';
                }
            }
        });
    }

    function addQueueRow(id, topic) {
        var row = document.createElement('div');
        row.className = 'amai-gap-queue-row';
        row.id = 'amai-gap-qrow-' + id;
        row.innerHTML =
            '<div class="amai-gap-queue-row-text">' +
                '<span class="amai-gap-queue-topic">' + escHtml(topic) + '</span>' +
            '</div>' +
            '<button type="button" class="amai-gap-queue-remove" data-id="' + id + '" title="Remove from queue">' +
                '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>' +
            '</button>';
        queueList.appendChild(row);
        bindQueueRemoveBtn(row.querySelector('.amai-gap-queue-remove'));
    }

    function bindQueueRemoveBtn(btn) {
        if (!btn) return;
        btn.addEventListener('click', function() {
            var id = btn.getAttribute('data-id');
            var fd = new FormData();
            fd.append('action', 'amai_competitor_gap_dequeue');
            fd.append('nonce', nonce);
            fd.append('id', id);
            fetch(ajaxurl, { method: 'POST', body: fd })
                .then(function(r) { return r.json(); })
                .then(function(data) {
                    if (data.success) {
                        var el = document.getElementById('amai-gap-qrow-' + id);
                        if (el) el.remove();
                        updateQueueState(data.data.queue_count, data.data.queue_full);
                        if (data.data.queue_count === 0) {
                            queueCard.style.display = 'none';
                        }
                    }
                });
        });
    }

    document.querySelectorAll('.amai-gap-queue-remove').forEach(function(btn) {
        bindQueueRemoveBtn(btn);
    });

    function renderGaps(gaps, title, queueFull) {
        gapList.innerHTML = '';
        resultsTitle.textContent = title || 'Content gaps found';
        var isFull = queueFull !== undefined ? queueFull : (queueCount >= maxQueue);

        gaps.forEach(function(gap, idx) {
            var row = document.createElement('div');
            row.className = 'amai-gap-row';
            row.id = 'amai-gap-row-' + idx;
            var sourceTag = gap.source ? '<span class="amai-gap-source-tag">' + escHtml(gap.source) + '</span>' : '';
            var queueBtnLabel = isFull ? 'Queue full' : 'Queue for Blog';
            var queueBtnDisabled = isFull ? ' disabled' : '';
            row.innerHTML =
                '<div class="amai-gap-row-content">' +
                    '<div class="amai-gap-topic">' + escHtml(gap.topic) + sourceTag + '</div>' +
                    '<div class="amai-gap-rationale">' + escHtml(gap.rationale) + '</div>' +
                '</div>' +
                '<div class="amai-gap-row-action">' +
                    '<button type="button" class="amai-gap-btn-queue amai-gap-btn-primary"' + queueBtnDisabled +
                        ' data-topic="' + escAttr(gap.topic) + '"' +
                        ' data-competitor-url="' + escAttr(gap.competitor_url || currentUrl) + '"' +
                        ' data-idx="' + idx + '">' + queueBtnLabel + '</button>' +
                '</div>';
            gapList.appendChild(row);
        });

        gapList.querySelectorAll('.amai-gap-btn-queue').forEach(function(btn) {
            btn.addEventListener('click', function() {
                if (btn.disabled || btn.classList.contains('amai-gap-btn-queued')) return;
                queueGap(
                    btn.getAttribute('data-topic'),
                    btn.getAttribute('data-competitor-url'),
                    btn.getAttribute('data-idx'),
                    btn
                );
            });
        });

        resultsWrap.style.display = 'block';
        resultsWrap.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }

    function queueGap(topic, competitorUrl, idx, btn) {
        btn.disabled = true;
        btn.textContent = 'Queuing...';

        var fd = new FormData();
        fd.append('action', 'amai_competitor_gap_queue');
        fd.append('nonce', nonce);
        fd.append('topic', topic);
        fd.append('competitor_url', competitorUrl || '');

        fetch(ajaxurl, { method: 'POST', body: fd })
            .then(function(r) { return r.json(); })
            .then(function(data) {
                if (data.success) {
                    btn.textContent = 'Queued';
                    btn.classList.add('amai-gap-btn-queued');
                    btn.disabled = true;
                    updateQueueState(data.data.queue_count, data.data.queue_full);
                    // We need the new row ID -- fetch it from the queue list (last appended)
                    // The server doesn't return the ID so we read the queue via a fresh getAll call
                    // Instead: add a placeholder row that will be confirmed on next page load.
                    // For now, do a lightweight re-fetch of the queue list to get the ID.
                    refreshQueueList();
                } else {
                    btn.disabled = false;
                    btn.textContent = 'Queue for Blog';
                    var msg = data.data && data.data.message ? data.data.message : 'Could not queue topic. Please try again.';
                    if (data.data && data.data.queue_full) {
                        updateQueueState(maxQueue, true);
                    }
                    alert(msg);
                }
            })
            .catch(function() {
                btn.disabled = false;
                btn.textContent = 'Queue for Blog';
                alert('Network error. Please try again.');
            });
    }

    function refreshQueueList() {
        var fd = new FormData();
        fd.append('action', 'amai_competitor_gap_queue_list');
        fd.append('nonce', nonce);
        fetch(ajaxurl, { method: 'POST', body: fd })
            .then(function(r) { return r.json(); })
            .then(function(data) {
                if (!data.success) return;
                queueList.innerHTML = '';
                var items = data.data.items || [];
                items.forEach(function(item) {
                    addQueueRow(item.id, item.topic);
                });
                updateQueueState(data.data.queue_count, data.data.queue_full);
                if (data.data.queue_count > 0) {
                    queueCard.style.display = 'block';
                }
            });
    }

    function runAnalyze(url, showSaveOnSuccess) {
        hideError();
        saveRow.style.display = 'none';
        setLoading(analyzeBtn, true);
        resultsWrap.style.display = 'none';
        gapList.innerHTML = '';

        var fd = new FormData();
        fd.append('action', 'amai_competitor_gap_analyze');
        fd.append('nonce', nonce);
        fd.append('url', url);

        fetch(ajaxurl, { method: 'POST', body: fd })
            .then(function(r) { return r.json(); })
            .then(function(data) {
                setLoading(analyzeBtn, false);
                if (data.success && data.data && data.data.gaps) {
                    renderGaps(data.data.gaps, 'Content gaps found', data.data.queue_full);
                    if (showSaveOnSuccess) {
                        currentUrl = url;
                        saveRow.style.display = 'flex';
                        saveBtn.disabled = false;
                        saveBtn.textContent = 'Save competitor';
                    }
                } else {
                    var msg = data.data && data.data.message ? data.data.message : 'Analysis failed. Please try again.';
                    showError(msg);
                }
            })
            .catch(function() {
                setLoading(analyzeBtn, false);
                showError('Network error. Please try again.');
            });
    }

    analyzeBtn.onclick = function() {
        var url = urlInput.value.trim();
        if (url === '') { showError('Please enter a competitor page URL.'); return; }
        if (!/^https?:\/\//i.test(url)) { showError('URL must start with http:// or https://'); return; }
        currentUrl = url;
        runAnalyze(url, true);
    };

    urlInput.addEventListener('keydown', function(e) {
        if (e.key === 'Enter') { analyzeBtn.click(); }
    });

    saveBtn.addEventListener('click', function() {
        if (!currentUrl) return;
        saveBtn.disabled = true;
        saveBtn.textContent = 'Saving...';

        var fd = new FormData();
        fd.append('action', 'amai_competitor_gap_save');
        fd.append('nonce', nonce);
        fd.append('url', currentUrl);

        fetch(ajaxurl, { method: 'POST', body: fd })
            .then(function(r) { return r.json(); })
            .then(function(data) {
                if (data.success) {
                    saveRow.style.display = 'none';
                    urlInput.value = '';
                    currentUrl = '';
                    addSavedRow(data.data.id, data.data.url, data.data.label);
                } else {
                    saveBtn.disabled = false;
                    saveBtn.textContent = 'Save competitor';
                }
            })
            .catch(function() {
                saveBtn.disabled = false;
                saveBtn.textContent = 'Save competitor';
            });
    });

    function addSavedRow(id, url, label) {
        savedCard.style.display = 'block';
        reanalyzeBtn.style.display = 'inline-flex';
        var row = document.createElement('div');
        row.className = 'amai-gap-saved-row';
        row.id = 'amai-gap-saved-' + id;
        row.innerHTML =
            '<div class="amai-gap-saved-info">' +
                '<span class="amai-gap-saved-name">' + escHtml(label) + '</span>' +
                '<span class="amai-gap-saved-url">' + escHtml(url) + '</span>' +
            '</div>' +
            '<div class="amai-gap-saved-actions">' +
                '<button type="button" class="amai-gap-btn-analyze-saved" data-url="' + escAttr(url) + '">Analyze</button>' +
                '<button type="button" class="amai-gap-btn-delete" data-id="' + id + '" title="Remove">' +
                    '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>' +
                '</button>' +
            '</div>';
        savedList.appendChild(row);
        bindSavedRowButtons(row);
    }

    function bindSavedRowButtons(row) {
        var btn2      = row.querySelector('.amai-gap-btn-analyze-saved');
        var deleteBtn = row.querySelector('.amai-gap-btn-delete');
        if (btn2) {
            btn2.addEventListener('click', function() {
                var url = btn2.getAttribute('data-url');
                urlInput.value = url;
                currentUrl = url;
                runAnalyze(url, false);
                window.scrollTo({ top: 0, behavior: 'smooth' });
            });
        }
        if (deleteBtn) {
            deleteBtn.addEventListener('click', function() {
                var id = deleteBtn.getAttribute('data-id');
                var fd = new FormData();
                fd.append('action', 'amai_competitor_gap_delete');
                fd.append('nonce', nonce);
                fd.append('id', id);
                fetch(ajaxurl, { method: 'POST', body: fd })
                    .then(function(r) { return r.json(); })
                    .then(function(data) {
                        if (data.success) {
                            var el = document.getElementById('amai-gap-saved-' + id);
                            if (el) el.remove();
                            if (savedList.children.length === 0) {
                                savedCard.style.display = 'none';
                            }
                        }
                    });
            });
        }
    }

    document.querySelectorAll('.amai-gap-saved-row').forEach(function(row) {
        bindSavedRowButtons(row);
    });

    if (reanalyzeBtn) {
        reanalyzeBtn.addEventListener('click', function() {
            setLoading(reanalyzeBtn, true);
            resultsWrap.style.display = 'none';
            gapList.innerHTML = '';
            hideError();
            saveRow.style.display = 'none';

            var fd = new FormData();
            fd.append('action', 'amai_competitor_gap_reanalyze');
            fd.append('nonce', nonce);

            fetch(ajaxurl, { method: 'POST', body: fd })
                .then(function(r) { return r.json(); })
                .then(function(data) {
                    setLoading(reanalyzeBtn, false);
                    if (data.success && data.data && data.data.gaps) {
                        renderGaps(data.data.gaps, 'Fresh content gaps from all competitors', data.data.queue_full);
                    } else {
                        var msg = data.data && data.data.message ? data.data.message : 'Re-analysis failed. Please try again.';
                        showError(msg);
                    }
                })
                .catch(function() {
                    setLoading(reanalyzeBtn, false);
                    showError('Network error. Please try again.');
                });
        });
    }

    function escHtml(str) {
        return String(str).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
    }
    function escAttr(str) {
        return String(str).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
    }

    // -- Competitor review mining --
    (function() {
        var rvNonce      = <?php echo wp_json_encode(wp_create_nonce('amai_competitor_gap')); ?>;
        var rvAjaxurl    = <?php echo wp_json_encode(admin_url('admin-ajax.php')); ?>;
        var rvMaxQueue   = <?php echo (int) \AutoMarketerAI\GapTopicQueue::MAX_QUEUE; ?>;
        var rvDomainInput  = document.getElementById('amai-rv-domain');
        var rvAnalyzeBtn   = document.getElementById('amai-rv-analyze-btn');
        var rvErrorBox     = document.getElementById('amai-rv-error');
        var rvResultsWrap  = document.getElementById('amai-rv-results');
        var rvResultsTitle = document.getElementById('amai-rv-results-title');
        var rvList         = document.getElementById('amai-rv-list');

        if (!rvAnalyzeBtn) { return; }

        function rvSetLoading(on) {
            rvAnalyzeBtn.disabled = on;
            var label   = rvAnalyzeBtn.querySelector('.amai-gap-btn-label');
            var spinner = rvAnalyzeBtn.querySelector('.amai-gap-btn-spinner');
            if (label)   { label.style.display   = on ? 'none'  : ''; }
            if (spinner) { spinner.style.display = on ? 'inline-block' : 'none'; }
        }
        function rvShowError(msg) {
            rvErrorBox.textContent = msg;
            rvErrorBox.style.display = '';
        }
        function rvHideError() { rvErrorBox.style.display = 'none'; }

        function renderOpportunities(opportunities, title, queueFull) {
            rvResultsTitle.textContent = title;
            rvList.innerHTML = '';
            opportunities.forEach(function(opp) {
                var row = document.createElement('div');
                row.className = 'amai-gap-row';
                var queuedClass = '';
                var actionHtml = queueFull
                    ? '<span class="amai-gap-queue-full-note">Queue full</span>'
                    : '<button type="button" class="amai-gap-queue-btn">Add to queue</button>';
                row.innerHTML =
                    '<div class="amai-gap-row-text">'
                    + '<span class="amai-gap-topic">' + escHtml(opp.topic) + '</span>'
                    + '<span class="amai-gap-rationale amai-rv-complaint">' + escHtml(opp.complaint) + '</span>'
                    + '<span class="amai-gap-rationale">' + escHtml(opp.angle) + '</span>'
                    + '</div>'
                    + '<div class="amai-gap-row-actions">' + actionHtml + '</div>';
                var qBtn = row.querySelector('.amai-gap-queue-btn');
                if (qBtn) {
                    qBtn.addEventListener('click', function() {
                        qBtn.disabled = true;
                        var fd2 = new FormData();
                        fd2.append('action', 'amai_competitor_gap_queue');
                        fd2.append('nonce', rvNonce);
                        fd2.append('topic', opp.topic);
                        fd2.append('competitor_url', rvDomainInput.value.trim());
                        fetch(rvAjaxurl, { method: 'POST', body: fd2 })
                            .then(function(r) { return r.json(); })
                            .then(function(d) {
                                if (d.success) {
                                    qBtn.textContent = 'Queued';
                                    qBtn.classList.add('amai-gap-queue-btn--queued');
                                    if (d.data && d.data.queue_full) {
                                        rvList.querySelectorAll('.amai-gap-queue-btn:not(.amai-gap-queue-btn--queued)').forEach(function(b) {
                                            b.disabled = true;
                                            b.textContent = 'Queue full';
                                        });
                                    }
                                } else {
                                    qBtn.disabled = false;
                                    qBtn.textContent = 'Try again';
                                }
                            })
                            .catch(function() { qBtn.disabled = false; });
                    });
                }
                rvList.appendChild(row);
            });
            rvResultsWrap.style.display = '';
        }

        rvAnalyzeBtn.addEventListener('click', function() {
            var domain = rvDomainInput.value.trim().replace(/^https?:\/\//i, '').replace(/\/.*$/, '');
            if (!domain) { rvShowError('Please enter a competitor domain.'); return; }
            rvHideError();
            rvResultsWrap.style.display = 'none';
            rvList.innerHTML = '';
            rvSetLoading(true);
            var fd = new FormData();
            fd.append('action', 'amai_competitor_reviews_analyze');
            fd.append('nonce', rvNonce);
            fd.append('domain', domain);
            fetch(rvAjaxurl, { method: 'POST', body: fd })
                .then(function(r) { return r.json(); })
                .then(function(data) {
                    rvSetLoading(false);
                    if (data.success && data.data && data.data.opportunities) {
                        renderOpportunities(
                            data.data.opportunities,
                            'Content opportunities from ' + escHtml(domain) + ' reviews',
                            data.data.queue_full
                        );
                    } else {
                        var msg = data.data && data.data.message ? data.data.message : 'Analysis failed. Please try again.';
                        rvShowError(msg);
                    }
                })
                .catch(function() {
                    rvSetLoading(false);
                    rvShowError('Network error. Please try again.');
                });
        });
    }());
})();
</script>