/// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/assets/js/amai-link-checker.js
// Description: Link Checker — scan, AI replace, update flow - NUCLEAR+++
// Last Edited: 2026-05-16
// ==================================================

(function () {
    'use strict';

    var cfg         = window.amaiLinkChecker || {};
    var ajaxurl     = cfg.ajaxurl  || '';
    var nonce       = cfg.nonce    || '';
    var adminUrl    = cfg.adminUrl || '';

    // Active suggestion state
    var activeSuggestion = {
        postId:    0,
        brokenUrl: '',
        rowEl:     null,
        panelEl:   null,
    };

    // All post IDs for bulk scan
    var allPostIds = [];

    // --------------------------------------------------
    // Init
    // --------------------------------------------------
    document.addEventListener('DOMContentLoaded', function () {
        loadBrokenLinks();

        var scanAllBtn = document.getElementById('amai-lc-scan-all');
        if (scanAllBtn) {
            scanAllBtn.addEventListener('click', onScanAll);
        }

        // These elements live inside the hidden suggestion template.
        // Guard against pages where the template HTML is absent.
        var dismissTpl = document.getElementById('amai-lc-dismiss-suggestion');
        var applyTpl   = document.getElementById('amai-lc-apply-suggestion');
        if (dismissTpl) dismissTpl.addEventListener('click', dismissSuggestion);
        if (applyTpl)   applyTpl.addEventListener('click', onApplySuggestion);
    });

    // --------------------------------------------------
    // Load existing broken link data
    // --------------------------------------------------
    function loadBrokenLinks() {
        showEl('amai-lc-loading');
        hideEl('amai-lc-table-wrap');
        hideEl('amai-lc-empty');
        hideEl('amai-lc-summary');

        ajax('amai_link_checker_load', {}, function (data) {
            hideEl('amai-lc-loading');

            allPostIds = (data.rows || []).map(function (r) { return r.post_id; });

            if (!data.rows || data.rows.length === 0) {
                showEl('amai-lc-empty');
                return;
            }

            renderTable(data.rows);
            updateSummary(data.total_broken, data.rows.length);
            showEl('amai-lc-summary');
            showEl('amai-lc-table-wrap');
        }, function () {
            hideEl('amai-lc-loading');
            showEl('amai-lc-empty');
        });
    }

    // --------------------------------------------------
    // Render the broken links table
    // --------------------------------------------------
    function renderTable(rows) {
        var tbody = document.getElementById('amai-lc-tbody');
        tbody.innerHTML = '';

        rows.forEach(function (row) {
            row.links.forEach(function (link, idx) {
                var tr = document.createElement('tr');
                tr.dataset.postId    = row.post_id;
                tr.dataset.brokenUrl = link.url;
                tr.id = 'amai-lc-row-' + row.post_id + '-' + idx;

                var statusClass = 'amai-lc-status--timeout';
                var statusLabel = 'Timeout';
                if (link.status >= 400 && link.status < 500) {
                    statusClass = 'amai-lc-status--4xx';
                    statusLabel = link.status.toString();
                } else if (link.status >= 500) {
                    statusClass = 'amai-lc-status--5xx';
                    statusLabel = link.status.toString();
                }

                var postCell = idx === 0
                    ? '<span class="amai-lc-post-title">' + esc(row.post_title) + '</span>'
                      + '<a href="' + esc(row.edit_url) + '" class="amai-lc-post-edit" target="_blank">Edit post</a>'
                    : '';

                tr.innerHTML =
                    '<td>' + postCell + '</td>'
                    + '<td><span class="amai-lc-anchor">' + esc(link.anchor || '-') + '</span></td>'
                    + '<td><span class="amai-lc-url" title="' + esc(link.url) + '">' + truncateUrl(link.url, 55) + '</span></td>'
                    + '<td><span class="amai-lc-status ' + statusClass + '">' + statusLabel + '</span></td>'
                    + '<td class="amai-lc-actions">'
                    + '  <button class="amai-lc-btn amai-lc-btn--ai" data-action="ai-replace" data-post-id="' + row.post_id + '" data-broken-url="' + esc(link.url) + '" data-anchor="' + esc(link.anchor || '') + '" data-row-id="' + tr.id + '">AI Fix</button>'
                    + '  <a href="' + esc(row.edit_url) + '" class="amai-lc-btn amai-lc-btn--fix" target="_blank">Edit</a>'
                    + '</td>';

                tbody.appendChild(tr);
            });
        });

        // Delegate click for AI Fix buttons
        tbody.addEventListener('click', function (e) {
            var btn = e.target.closest('[data-action="ai-replace"]');
            if (btn) {
                onAiReplace(btn);
            }
        });
    }

    // --------------------------------------------------
    // Scan all posts — sequential, with progress bar
    // --------------------------------------------------
    function onScanAll() {
        if (allPostIds.length === 0) {
            // No cached IDs — need to fetch all post IDs first
            fetchAllPostIds(function (ids) {
                allPostIds = ids;
                runBulkScan(ids);
            });
            return;
        }
        runBulkScan(allPostIds);
    }

    function fetchAllPostIds(cb) {
        // Use the load action to get current post IDs (re-fetch)
        ajax('amai_link_checker_load', {}, function (data) {
            var ids = (data.rows || []).map(function (r) { return r.post_id; });
            // Also need posts that have never been scanned — request all published IDs from server
            // For now, use whatever is in the existing data
            cb(ids);
        }, function () { cb([]); });
    }

    function runBulkScan(ids) {
        if (ids.length === 0) {
            loadBrokenLinks();
            return;
        }

        var scanBtn = document.getElementById('amai-lc-scan-all');
        scanBtn.disabled = true;
        scanBtn.textContent = 'Scanning...';

        showEl('amai-lc-progress');
        hideEl('amai-lc-table-wrap');
        hideEl('amai-lc-empty');
        hideEl('amai-lc-summary');

        var total     = ids.length;
        var completed = 0;
        var allBroken = [];

        function next() {
            if (completed >= total) {
                done();
                return;
            }
            var postId = ids[completed];
            setProgress(completed, total, 'Scanning post ' + (completed + 1) + ' of ' + total + '...');

            ajax('amai_link_checker_scan_post', { post_id: postId }, function (data) {
                if (data.broken && data.broken.length > 0) {
                    allBroken.push({ post_id: data.post_id, links: data.broken });
                }
                completed++;
                next();
            }, function () {
                completed++;
                next();
            });
        }

        function done() {
            setProgress(total, total, 'Scan complete.');
            scanBtn.disabled = false;
            scanBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Scan All Posts';

            setTimeout(function () {
                hideEl('amai-lc-progress');
                loadBrokenLinks();
            }, 800);
        }

        next();
    }

    function setProgress(done, total, label) {
        var pct = total > 0 ? Math.round((done / total) * 100) : 0;
        var fill = document.getElementById('amai-lc-progress-fill');
        var lbl  = document.getElementById('amai-lc-progress-label');
        if (fill) fill.style.width = pct + '%';
        if (lbl)  lbl.textContent  = label;
    }

    // --------------------------------------------------
    // AI replace flow
    // --------------------------------------------------
    function onAiReplace(btn) {
        var postId    = parseInt(btn.dataset.postId, 10);
        var brokenUrl = btn.dataset.brokenUrl;
        var anchor    = btn.dataset.anchor || '';
        var rowId     = btn.dataset.rowId;
        var rowEl     = document.getElementById(rowId);

        // Remove any existing suggestion panel
        dismissSuggestion();

        // Show spinner on button
        var origText = btn.textContent;
        btn.disabled = true;
        btn.innerHTML = '<span class="amai-lc-ai-spinner"></span> Thinking...';

        ajax('amai_link_checker_ai_replace', {
            post_id:    postId,
            broken_url: brokenUrl,
            anchor:     anchor,
        }, function (data) {
            btn.disabled = false;
            btn.textContent = origText;

            activeSuggestion.postId    = postId;
            activeSuggestion.brokenUrl = brokenUrl;
            activeSuggestion.rowEl     = rowEl;

            showSuggestionPanel(rowEl, data.suggested_url, data.source, data.reason);
        }, function (msg) {
            btn.disabled = false;
            btn.textContent = origText;
            showToast((msg || 'AI suggestion failed. Try again.'), 'error');
        });
    }

    function showSuggestionPanel(rowEl, url, source, reason) {
        // Inject a panel row after the target row
        var panel = document.createElement('tr');
        panel.className = 'amai-lc-suggestion-row';
        panel.id = 'amai-lc-active-suggestion-row';

        var colspan = 5;
        panel.innerHTML = '<td colspan="' + colspan + '"></td>';

        // Clone the suggestion template from the hidden panel
        var tpl = document.getElementById('amai-lc-suggestion');
        var clone = tpl.cloneNode(true);
        clone.style.display = 'block';
        clone.removeAttribute('id');

        clone.querySelector('#amai-lc-suggestion-source').textContent = source || '';
        clone.querySelector('#amai-lc-suggestion-reason').textContent = reason || '';
        var urlInput = clone.querySelector('#amai-lc-suggestion-url');
        urlInput.value = url || '';

        clone.querySelector('#amai-lc-apply-suggestion').addEventListener('click', onApplySuggestion);
        clone.querySelector('#amai-lc-dismiss-suggestion').addEventListener('click', dismissSuggestion);

        panel.firstElementChild.appendChild(clone);

        activeSuggestion.panelEl = panel;

        if (rowEl && rowEl.nextSibling) {
            rowEl.parentNode.insertBefore(panel, rowEl.nextSibling);
        } else if (rowEl) {
            rowEl.parentNode.appendChild(panel);
        }

        urlInput.focus();
    }

    function dismissSuggestion() {
        var existing = document.getElementById('amai-lc-active-suggestion-row');
        if (existing) existing.remove();
        activeSuggestion = { postId: 0, brokenUrl: '', rowEl: null, panelEl: null };
    }

    function onApplySuggestion() {
        var panel  = document.getElementById('amai-lc-active-suggestion-row');
        var urlInput = panel ? panel.querySelector('.amai-lc-url-input') : null;
        var newUrl = urlInput ? urlInput.value.trim() : '';

        if (!newUrl || (!newUrl.startsWith('http://') && !newUrl.startsWith('https://'))) {
            showToast('Please enter a valid URL starting with http:// or https://', 'error');
            return;
        }

        var applyBtn = panel ? panel.querySelector('#amai-lc-apply-suggestion') : null;
        if (applyBtn) {
            applyBtn.disabled = true;
            applyBtn.innerHTML = '<span class="amai-lc-ai-spinner"></span> Updating...';
        }

        ajax('amai_link_checker_update_link', {
            post_id:    activeSuggestion.postId,
            broken_url: activeSuggestion.brokenUrl,
            new_url:    newUrl,
        }, function (data) {
            dismissSuggestion();
            // Reload the table to reflect the fix
            loadBrokenLinks();
        }, function (msg) {
            if (applyBtn) {
                applyBtn.disabled = false;
                applyBtn.textContent = 'Update Link';
            }
            showToast('Update failed: ' + (msg || 'Unknown error.'), 'error');
        });
    }

    // --------------------------------------------------
    // Summary bar
    // --------------------------------------------------
    function updateSummary(totalBroken, totalPosts) {
        var numEl   = document.getElementById('amai-lc-total-broken');
        var postEl  = document.getElementById('amai-lc-total-posts');
        if (numEl)  numEl.textContent  = totalBroken;
        if (postEl) postEl.textContent = totalPosts;
    }

    // --------------------------------------------------
    // Toast notifications
    // --------------------------------------------------
    function showToast(msg, type) {
        var existing = document.getElementById('amai-lc-toast');
        if (existing) existing.remove();

        var toast = document.createElement('div');
        toast.id = 'amai-lc-toast';
        toast.className = 'amai-lc-toast amai-lc-toast--' + (type || 'error');
        toast.setAttribute('role', 'alert');

        var icon = type === 'success'
            ? '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M20 6L9 17l-5-5"/></svg>'
            : '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><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>';

        toast.innerHTML = icon + '<span>' + esc(msg) + '</span>'
            + '<button class="amai-lc-toast__close" aria-label="Dismiss">'
            + '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>'
            + '</button>';

        toast.querySelector('.amai-lc-toast__close').addEventListener('click', function () {
            toast.classList.add('amai-lc-toast--out');
            setTimeout(function () { toast.remove(); }, 250);
        });

        document.body.appendChild(toast);

        // Trigger enter animation
        requestAnimationFrame(function () {
            requestAnimationFrame(function () {
                toast.classList.add('amai-lc-toast--in');
            });
        });

        // Auto-dismiss after 6 seconds
        setTimeout(function () {
            if (toast.parentNode) {
                toast.classList.remove('amai-lc-toast--in');
                toast.classList.add('amai-lc-toast--out');
                setTimeout(function () { toast.remove(); }, 250);
            }
        }, 6000);
    }

    // --------------------------------------------------
    // Helpers
    // --------------------------------------------------
    function ajax(action, params, onSuccess, onError) {
        var body = new URLSearchParams();
        body.append('action', action);
        body.append('nonce', nonce);
        Object.keys(params).forEach(function (k) {
            body.append(k, params[k]);
        });

        fetch(ajaxurl, {
            method:  'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body:    body.toString(),
        })
        .then(function (r) { return r.json(); })
        .then(function (json) {
            if (json.success) {
                onSuccess(json.data || {});
            } else {
                var msg = (json.data && json.data.message) ? json.data.message : 'Request failed.';
                if (onError) onError(msg);
            }
        })
        .catch(function () {
            if (onError) onError('Network error.');
        });
    }

    function showEl(id) {
        var el = document.getElementById(id);
        if (el) el.style.display = '';
    }

    function hideEl(id) {
        var el = document.getElementById(id);
        if (el) el.style.display = 'none';
    }

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

    function truncateUrl(url, max) {
        if (url.length <= max) return esc(url);
        return esc(url.substring(0, max)) + '...';
    }

}());