/**
 * AG Auto Click & Scroll — Browser Inject Script
 * Adapted from zixfel/ag-auto-click-scroll extension
 * 
 * This script runs inside Antigravity's workbench webview.
 * It auto-clicks buttons (Run, Allow, Accept...) and auto-scrolls the chat panel.
 * Config is loaded from a JSON file written by the toolkit server.
 */
(function () {
    if (window._agAutoLoaded) return;
    window._agAutoLoaded = true;

    if (window._agToolIntervals) {
        window._agToolIntervals.forEach(clearInterval);
        window.removeEventListener('scroll', window._agScrollListener, true);
    }
    window._agToolIntervals = [];

    // === Suppress "corrupt installation" banner ===
    (function suppressCorruptBanner() {
        function dismissCorrupt() {
            var banners = document.querySelectorAll('.notifications-toasts .notification-toast, .notification-list-item');
            banners.forEach(function (banner) {
                var text = banner.textContent || '';
                if (text.indexOf('corrupt') === -1 && text.indexOf('reinstall') === -1) return;
                var closeBtn = banner.querySelector('.codicon-notifications-clear, .codicon-close, .action-label[aria-label*="Close"], .action-label[aria-label*="clear"], .clear-notification-action');
                if (closeBtn) { closeBtn.click(); console.log('[AG Auto] Dismissed corrupt notification'); }
                else { banner.style.display = 'none'; console.log('[AG Auto] Hid corrupt notification'); }
            });
        }
        dismissCorrupt();
        var attempts = 0;
        var timer = setInterval(function () { dismissCorrupt(); if (++attempts > 30) clearInterval(timer); }, 1000);
        try {
            var observer = new MutationObserver(function () { dismissCorrupt(); });
            observer.observe(document.body || document.documentElement, { childList: true, subtree: true });
            setTimeout(function () { observer.disconnect(); }, 30000);
        } catch (e) { }
    })();

    // === Config defaults (overridden by config file) ===
    var PAUSE_SCROLL_MS = 7000;
    var CLICK_INTERVAL_MS = 1000;
    var SCROLL_INTERVAL_MS = 500;
    var CLICK_PATTERNS = ["Run", "Allow", "Always Allow", "Keep Waiting", "Accept", "Accept all"];

    window._agAcceptChatOnly = true;
    window._agAutoEnabled = true;
    window._agScrollEnabled = true;

    // === Config file path (injected during install) ===
    var CONFIG_PATH = '/*{{CONFIG_PATH}}*/';

    var _agSessionStats = {};
    var _agSessionTotal = 0;
    var _agLastContentChange = 0;
    var _agContentActiveUntil = 0;
    var _agManualPauseUntil = 0;
    var _agAutoScrollGuardUntil = 0;
    var _agScrollObserver = null;
    var _agObservedChatPanel = null;
    var _agObserverWatchdog = 0;
    var _agAutoScrollInterval = 0;
    var _agAutoScrollKickTimer = 0;
    var _agLastJumpButtonClickAt = 0;
    var isAutoScrolling = false;

    function _agClampMs(value, fallback, minValue, maxValue) {
        var num = Number(value);
        if (!isFinite(num)) num = Number(fallback);
        if (!isFinite(num)) num = minValue;
        return Math.max(minValue, Math.min(maxValue, Math.round(num)));
    }

    function _agScrollPauseWindowMs() { return _agClampMs(PAUSE_SCROLL_MS, 7000, 1000, 60000); }
    function _agScrollTickMs() { return _agClampMs(SCROLL_INTERVAL_MS, 500, 100, 5000); }
    function _agContentActivityWindowMs() { return Math.max(2500, Math.min(8000, Math.round(_agScrollPauseWindowMs() * 0.6))); }

    function _agNormalizeNode(node) {
        if (!node) return null;
        if (node === window) return document.documentElement;
        if (node.nodeType === 3) return node.parentElement;
        return node.nodeType === 1 ? node : null;
    }

    function _agGetChatPanel() { return document.querySelector('.antigravity-agent-side-panel'); }

    function _agIsInsideChatPanel(node) {
        var el = _agNormalizeNode(node);
        return !!(el && el.closest && el.closest('.antigravity-agent-side-panel'));
    }

    function _agIsInputArea(node) {
        var el = _agNormalizeNode(node);
        return !!(el && (
            el.tagName === 'TEXTAREA' || el.tagName === 'INPUT' || el.isContentEditable ||
            (el.closest && (
                el.closest('textarea') || el.closest('[contenteditable="true"]') ||
                el.closest('[contenteditable="plaintext-only"]') || el.closest('.chat-input') ||
                el.closest('.interactive-input-part') || el.closest('.interactive-input') ||
                el.closest('.monaco-inputbox') || el.closest('.input-editor')
            ))
        ));
    }

    function _agKickAutoScrollSoon(delayMs) {
        if (_agAutoScrollKickTimer) return;
        _agAutoScrollKickTimer = setTimeout(function () {
            _agAutoScrollKickTimer = 0;
            _agRunAutoScrollTick();
        }, delayMs || 40);
    }

    function _agMarkContentActivity() {
        var now = Date.now();
        _agLastContentChange = now;
        _agContentActiveUntil = now + _agContentActivityWindowMs();
        _agKickAutoScrollSoon(40);
    }

    // === Config reload from file (via fetch) ===
    function _agApplyConfig(cfg) {
        if (typeof cfg.enabled === 'boolean') {
            if (window._agAutoEnabled !== cfg.enabled) {
                console.log('[AG Auto] ' + (cfg.enabled ? 'ON' : 'OFF') + ' (config update)');
            }
            window._agAutoEnabled = cfg.enabled;
        }
        if (typeof cfg.scrollEnabled === 'boolean') window._agScrollEnabled = cfg.scrollEnabled;
        if (cfg.clickPatterns && Array.isArray(cfg.clickPatterns)) {
            CLICK_PATTERNS = cfg.clickPatterns;
        }
        if (typeof cfg.acceptInChatOnly === 'boolean') window._agAcceptChatOnly = cfg.acceptInChatOnly;
        if (typeof cfg.pauseScrollMs === 'number') {
            PAUSE_SCROLL_MS = _agClampMs(cfg.pauseScrollMs, PAUSE_SCROLL_MS, 1000, 60000);
        }
        if (typeof cfg.scrollIntervalMs === 'number') {
            var nextScrollInterval = _agClampMs(cfg.scrollIntervalMs, SCROLL_INTERVAL_MS, 100, 5000);
            if (nextScrollInterval !== SCROLL_INTERVAL_MS) {
                SCROLL_INTERVAL_MS = nextScrollInterval;
                _agRestartAutoScrollLoop();
            }
        }
        if (typeof cfg.clickIntervalMs === 'number') {
            var nextClickInterval = _agClampMs(cfg.clickIntervalMs, CLICK_INTERVAL_MS, 100, 5000);
            if (nextClickInterval !== CLICK_INTERVAL_MS) {
                CLICK_INTERVAL_MS = nextClickInterval;
                _agRestartAutoClickLoop();
            }
        }
    }

    // Reload config from JSON file periodically
    var _agConfigPollCount = 0;
    var _agConfigReload = setInterval(function () {
        _agConfigPollCount++;
        if (!CONFIG_PATH || CONFIG_PATH.indexOf('{{CONFIG_PATH}}') !== -1) return;
        try {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'vscode-file://vscode-app/' + CONFIG_PATH + '?t=' + Date.now(), true);
            xhr.timeout = 2000;
            xhr.onload = function () {
                if (xhr.status === 200) {
                    try {
                        var cfg = JSON.parse(xhr.responseText);
                        _agApplyConfig(cfg);
                        if (_agConfigPollCount <= 2) {
                            console.log('[AG Auto] Config loaded, enabled=' + window._agAutoEnabled + ', patterns=' + CLICK_PATTERNS.length);
                        }
                    } catch (e) { }
                }
            };
            xhr.onerror = function () { };
            xhr.ontimeout = function () { };
            xhr.send();
        } catch (e) { }
    }, 3000);
    window._agToolIntervals.push(_agConfigReload);

    // === Scroll Observer ===
    function _agHasMeaningfulMutation(mutation) {
        var node = _agNormalizeNode(mutation.target);
        if (!node || !_agIsInsideChatPanel(node) || _agIsInputArea(node)) return false;
        if (mutation.type === 'characterData') return true;
        if (mutation.type === 'childList') return mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0;
        if (mutation.type === 'attributes') {
            return ['class', 'style', 'aria-expanded', 'aria-busy', 'open', 'data-state'].indexOf(mutation.attributeName || '') !== -1;
        }
        return false;
    }

    function _agEnsureScrollObserver() {
        var chatPanel = _agGetChatPanel();
        if (!chatPanel) return false;
        if (_agObservedChatPanel === chatPanel && _agScrollObserver) return true;
        if (_agScrollObserver) { try { _agScrollObserver.disconnect(); } catch (e) { } }
        _agObservedChatPanel = chatPanel;
        _agScrollObserver = new MutationObserver(function (mutations) {
            for (var i = 0; i < mutations.length; i++) {
                if (_agHasMeaningfulMutation(mutations[i])) { _agMarkContentActivity(); return; }
            }
        });
        _agScrollObserver.observe(chatPanel, {
            childList: true, subtree: true, characterData: true, attributes: true,
            attributeFilter: ['class', 'style', 'aria-expanded', 'aria-busy', 'open', 'data-state']
        });
        _agMarkContentActivity();
        console.log('[AG Auto] Smart scroll observer attached');
        return true;
    }

    function _agElementDepth(el) { var d = 0; while (el && el.parentElement) { d++; el = el.parentElement; } return d; }

    function _agCollectScrollTargets(chatPanel) {
        var nodes = [chatPanel].concat(Array.from(chatPanel.querySelectorAll('*')));
        return nodes.filter(function (el) {
            if (!el || el.nodeType !== 1) return false;
            if (!el.closest || !el.closest('.antigravity-agent-side-panel')) return false;
            if (el.closest('.monaco-editor') || el.closest('.part.editor')) return false;
            if (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT') return false;
            var style = window.getComputedStyle(el);
            var overflowY = style.overflowY;
            var hasScrollbar = el.scrollHeight > (el.clientHeight + 4);
            if (!hasScrollbar) return false;
            return overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay';
        }).sort(function (a, b) { return _agElementDepth(b) - _agElementDepth(a); });
    }

    function _agScrollElementToBottom(el) {
        var maxScrollTop = Math.max(0, el.scrollHeight - el.clientHeight);
        var gap = maxScrollTop - el.scrollTop;
        if (gap <= 2) return false;
        try { el.scrollTo({ top: maxScrollTop, behavior: 'auto' }); } catch (e) { el.scrollTop = maxScrollTop; }
        return true;
    }

    function _agGetLargestScrollGap(scrollables) {
        var maxGap = 0;
        scrollables.forEach(function (el) {
            var gap = Math.max(0, el.scrollHeight - el.clientHeight - el.scrollTop);
            if (gap > maxGap) maxGap = gap;
        });
        return maxGap;
    }

    function _agFindJumpToBottomButton(chatPanel) {
        if (!chatPanel) return null;
        var panelRect = chatPanel.getBoundingClientRect();
        if (!panelRect || panelRect.width <= 0 || panelRect.height <= 0) return null;
        var candidates = Array.from(chatPanel.querySelectorAll('button, [role="button"]'));
        var best = null, bestScore = -Infinity;
        candidates.forEach(function (btn) {
            if (!btn || btn.offsetParent === null) return;
            if (_agIsInputArea(btn)) return;
            if (btn.closest && (btn.closest('.monaco-editor') || btn.closest('.part.editor'))) return;
            var rect = btn.getBoundingClientRect();
            if (!rect || rect.width < 16 || rect.height < 16 || rect.width > 72 || rect.height > 72) return;
            var gapRight = panelRect.right - rect.right;
            var gapBottom = panelRect.bottom - rect.bottom;
            if (gapRight < -4 || gapBottom < -4) return;
            if (gapRight > 120 || gapBottom > 160) return;
            var rawText = ((btn.innerText || btn.textContent || '') + ' ' + (btn.getAttribute('aria-label') || '') + ' ' + (btn.getAttribute('title') || '')).trim();
            var text = rawText.replace(/\s+/g, ' ').trim();
            var lower = text.toLowerCase();
            var hasSvg = !!btn.querySelector('svg, path, [data-icon], .codicon');
            var isDownSemantic = lower === '↓' || lower === '▼' || lower === '⌄' || /scroll|bottom|latest|new|down|jump/.test(lower);
            var isIconOnly = text.length === 0 && hasSvg;
            if (!isDownSemantic && !isIconOnly) return;
            var horizontalBias = Math.max(0, 160 - gapRight);
            var verticalBias = Math.max(0, 180 - gapBottom);
            var score = horizontalBias + verticalBias + (isIconOnly ? 35 : 0) + (isDownSemantic ? 55 : 0);
            if (score > bestScore) { bestScore = score; best = btn; }
        });
        return best;
    }

    function _agClickJumpToBottomButton(btn) {
        if (!btn) return false;
        var now = Date.now();
        if (now - _agLastJumpButtonClickAt < 700) return false;
        _agLastJumpButtonClickAt = now;
        _agAutoScrollGuardUntil = now + 250;
        try { btn.click(); console.log('[AG Auto] Jump-to-bottom button clicked'); } catch (e) { return false; }
        _agContentActiveUntil = Math.max(_agContentActiveUntil, now + 1500);
        _agKickAutoScrollSoon(120);
        return true;
    }

    function _agRunAutoScrollTick() {
        _agEnsureScrollObserver();
        if (!window._agAutoEnabled) return false;
        if (!window._agScrollEnabled) return false;
        var now = Date.now();
        if (now < _agManualPauseUntil) return false;
        if (_agLastContentChange === 0 || now > _agContentActiveUntil) return false;
        var chatPanel = _agObservedChatPanel || _agGetChatPanel();
        if (!chatPanel) return false;
        var scrollables = _agCollectScrollTargets(chatPanel);
        if (scrollables.length === 0) return false;
        var scrolledAny = false;
        var largestGap = _agGetLargestScrollGap(scrollables);
        _agAutoScrollGuardUntil = now + 150;
        isAutoScrolling = true;
        try {
            if (largestGap > 48) {
                var jumpBtn = _agFindJumpToBottomButton(chatPanel);
                if (_agClickJumpToBottomButton(jumpBtn)) scrolledAny = true;
            }
            scrollables.forEach(function (el) { if (_agScrollElementToBottom(el)) scrolledAny = true; });
        } finally { setTimeout(function () { isAutoScrolling = false; }, 100); }
        return scrolledAny;
    }

    function _agStartAutoScrollLoop() {
        if (_agAutoScrollInterval) clearInterval(_agAutoScrollInterval);
        var tickMs = _agScrollTickMs();
        _agAutoScrollInterval = setInterval(function () { _agRunAutoScrollTick(); }, tickMs);
        window._agToolIntervals.push(_agAutoScrollInterval);
        console.log('[AG Auto] Smart auto-scroll loop started (' + tickMs + 'ms)');
    }

    function _agRestartAutoScrollLoop() { _agStartAutoScrollLoop(); }

    // === Auto Click Logic ===
    var REJECT_WORDS = ['Reject', 'Deny', 'Cancel', 'Dismiss', "Don't Allow", 'Decline'];
    var EDITOR_SKIP_WORDS = ['Accept Changes', 'Accept All', 'Accept Incoming', 'Accept Current', 'Accept Both', 'Accept Combination'];
    var _clicked = new WeakSet();

    function isApprovalButton(btn) {
        var parent = btn.parentElement;
        if (!parent) return false;
        for (var level = 0; level < 3; level++) {
            if (!parent) break;
            var siblingBtns = parent.querySelectorAll('button, a.action-label, [role="button"], .monaco-button, span.bg-ide-button-background');
            for (var i = 0; i < siblingBtns.length; i++) {
                var sibling = siblingBtns[i];
                if (sibling === btn) continue;
                var siblingText = (sibling.innerText || '').trim();
                for (var j = 0; j < REJECT_WORDS.length; j++) {
                    if (siblingText === REJECT_WORDS[j] || siblingText.indexOf(REJECT_WORDS[j]) === 0) return true;
                }
            }
            parent = parent.parentElement;
        }
        return false;
    }

    if (!window._agClickStats) window._agClickStats = {};
    if (!window._agTotalClicks) window._agTotalClicks = 0;

    var _agAutoClickInterval = 0;

    function _agAutoClickLogic() {
        if (!window._agAutoEnabled) return;

        var clickables = Array.from(document.querySelectorAll('button, a.action-label, [role="button"], .monaco-button'));
        document.querySelectorAll('span.cursor-pointer').forEach(function (span) { clickables.push(span); });

        var targetBtn = null;
        var matchedPattern = '';

        // Filter out Accept from normal patterns — handle separately if acceptInChatOnly
        var normalPatterns = CLICK_PATTERNS.filter(function (p) { return p !== 'Accept'; });

        for (var i = 0; i < clickables.length; i++) {
            var btn = clickables[i];
            if (btn.offsetParent === null) continue;
            if (_clicked.has(btn)) continue;

            var text = (btn.innerText || btn.textContent || '').trim();
            if (!text || text.length > 40) continue;

            var skipEditor = false;
            for (var se = 0; se < EDITOR_SKIP_WORDS.length; se++) {
                if (text.indexOf(EDITOR_SKIP_WORDS[se]) === 0) { skipEditor = true; break; }
            }
            if (skipEditor) continue;

            if (btn.closest && (
                btn.closest('.monaco-diff-editor') || btn.closest('.merge-editor-view') ||
                btn.closest('.inline-merge-region') || btn.closest('.merged-editor') ||
                btn.closest('.view-zones') || btn.closest('.view-lines') ||
                btn.closest('[id*="workbench.parts.editor"]')
            )) continue;

            if (btn.classList && (btn.classList.contains('diff-hunk-button') || btn.classList.contains('accept') || btn.classList.contains('revert'))) {
                var editorAncestor = btn.closest && btn.closest('[class*="editor"], [id*="editor"]');
                if (editorAncestor) continue;
            }

            var matchesPattern = false;
            for (var p = 0; p < normalPatterns.length; p++) {
                var pattern = normalPatterns[p];
                if (text === pattern || text.indexOf(pattern) === 0) {
                    matchesPattern = true;
                    matchedPattern = pattern;
                    break;
                }
            }
            if (!matchesPattern) continue;

            if (btn.tagName === 'SPAN' && btn.classList.contains('cursor-pointer')) { targetBtn = btn; break; }
            if (isApprovalButton(btn)) { targetBtn = btn; break; }
        }

        // Accept in chat only
        if (!targetBtn && window._agAcceptChatOnly) {
            for (var ai = 0; ai < clickables.length; ai++) {
                var acceptBtn = clickables[ai];
                if (acceptBtn.offsetParent === null) continue;
                if (_clicked.has(acceptBtn)) continue;
                var acceptText = (acceptBtn.innerText || acceptBtn.textContent || '').trim();
                if (acceptText.indexOf('Accept') !== 0) continue;
                if (/^Accept\s+(all|changes|incoming|current|both|combination)/i.test(acceptText)) continue;
                if (acceptBtn.closest && (
                    acceptBtn.closest('.editor-scrollable') || acceptBtn.closest('.monaco-diff-editor') ||
                    acceptBtn.closest('.view-zones') || acceptBtn.closest('.merge-editor-view')
                )) continue;
                if (acceptBtn.classList && (acceptBtn.classList.contains('diff-hunk-button') || acceptBtn.classList.contains('revert'))) continue;
                targetBtn = acceptBtn;
                matchedPattern = 'Accept';
                break;
            }
        }

        if (targetBtn) {
            console.log('[AG Auto] Click: [' + targetBtn.innerText.trim() + ']');
            _clicked.add(targetBtn);
            targetBtn.click();
            _agSessionTotal++;
            if (!_agSessionStats[matchedPattern]) _agSessionStats[matchedPattern] = 0;
            _agSessionStats[matchedPattern]++;
            window._agTotalClicks++;
            if (!window._agClickStats[matchedPattern]) window._agClickStats[matchedPattern] = 0;
            window._agClickStats[matchedPattern]++;
        }
    }

    function _agRestartAutoClickLoop() {
        if (_agAutoClickInterval) clearInterval(_agAutoClickInterval);
        _agAutoClickInterval = setInterval(_agAutoClickLogic, CLICK_INTERVAL_MS);
        window._agToolIntervals.push(_agAutoClickInterval);
    }
    _agRestartAutoClickLoop();

    // === Start scroll observer ===
    function _agStartScrollObserver() {
        _agEnsureScrollObserver();
        if (_agObserverWatchdog) return;
        _agObserverWatchdog = setInterval(function () { _agEnsureScrollObserver(); }, 1500);
        window._agToolIntervals.push(_agObserverWatchdog);
    }

    _agStartScrollObserver();

    window._agScrollListener = function (e) {
        if (!e.isTrusted) return;
        if (isAutoScrolling && Date.now() < _agAutoScrollGuardUntil) return;
        if (!_agIsInsideChatPanel(e.target)) return;
        _agManualPauseUntil = Date.now() + _agScrollPauseWindowMs();
    };
    window.addEventListener('scroll', window._agScrollListener, true);

    _agStartAutoScrollLoop();
    console.log('[AG Auto] Toolkit inject ready | Patterns:', JSON.stringify(CLICK_PATTERNS));
})();
