// Pidgey Assist — Content Script
// Handles: leaf border animation + page interaction tools

let leafOverlay = null;
let pidgeyMascot = null;

// ======== DOM MASCOT ========
function createPidgeyMascot() {
    if (pidgeyMascot) return pidgeyMascot;

    const el = document.createElement('div');
    el.id = 'pidgey-dom-mascot';

    // We get the extension URL for the 128px icon
    const iconUrl = chrome.runtime.getURL('icons/icon128.png');

    el.setAttribute('style', `
      position: fixed !important;
      bottom: 20px !important;
      right: 20px !important;
      width: 65px !important;
      height: 65px !important;
      z-index: 2147483647 !important;
      pointer-events: auto !important;
      cursor: grab !important;
      background-image: url('${iconUrl}') !important;
      background-size: contain !important;
      background-repeat: no-repeat !important;
      background-position: center !important;
      transition: top 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), left 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
      filter: drop-shadow(0 4px 10px rgba(0,0,0,0.3)) !important;
      animation: pidgey-idle 3s ease-in-out infinite !important;
    `);

    const styleSheet = document.createElement('style');
    styleSheet.textContent = `
      @keyframes pidgey-idle {
        0%, 100% { transform: translateY(0); }
        50% { transform: translateY(-5px); }
      }
      @keyframes pidgey-thinking {
        0% { transform: rotate(0deg) scale(1.1); }
        25% { transform: rotate(-8deg) scale(1.1); }
        75% { transform: rotate(8deg) scale(1.1); }
        100% { transform: rotate(0deg) scale(1.1); }
      }
      @keyframes pidgey-peck {
        0% { transform: rotate(0deg) translateY(0); }
        50% { transform: rotate(25deg) translateY(10px) translateX(-5px); }
        100% { transform: rotate(0deg) translateY(0); }
      }
    `;
    el.appendChild(styleSheet);

    // Make draggable
    let isDragging = false;
    let startX, startY, initialLeft, initialTop;

    el.addEventListener('mousedown', (e) => {
        isDragging = true;
        el.style.setProperty('cursor', 'grabbing', 'important');
        el.style.setProperty('transition', 'none', 'important');

        const rect = el.getBoundingClientRect();
        startX = e.clientX;
        startY = e.clientY;
        initialLeft = rect.left;
        initialTop = rect.top;

        el.style.setProperty('bottom', 'auto', 'important');
        el.style.setProperty('right', 'auto', 'important');
        el.style.setProperty('left', initialLeft + 'px', 'important');
        el.style.setProperty('top', initialTop + 'px', 'important');

        e.preventDefault();
    });

    document.addEventListener('mousemove', (e) => {
        if (!isDragging) return;
        const dx = e.clientX - startX;
        const dy = e.clientY - startY;
        el.style.setProperty('left', (initialLeft + dx) + 'px', 'important');
        el.style.setProperty('top', (initialTop + dy) + 'px', 'important');
    });

    document.addEventListener('mouseup', () => {
        if (isDragging) {
            isDragging = false;
            el.style.setProperty('cursor', 'grab', 'important');
            el.style.setProperty('transition', 'top 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), left 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)', 'important');
        }
    });

    // Happy Chirp on Click (petting the bird)
    el.addEventListener('click', (e) => {
        if (e.clientX !== startX || e.clientY !== startY) return; // Ignore drag clicks

        el.style.setProperty('animation', 'none', 'important');
        void el.offsetWidth; // Trigger reflow
        el.style.setProperty('animation', 'pidgey-peck 0.3s ease-in-out', 'important');
        setTimeout(() => {
            el.style.setProperty('animation', 'pidgey-idle 3s ease-in-out infinite', 'important');
        }, 300);
    });

    document.documentElement.appendChild(el);
    pidgeyMascot = el;
    return el;
}

function setMascotState(state) {
    const el = createPidgeyMascot();
    if (state === 'thinking') {
        el.style.setProperty('animation', 'pidgey-thinking 1.2s ease-in-out infinite', 'important');
    } else {
        el.style.setProperty('animation', 'pidgey-idle 3s ease-in-out infinite', 'important');
    }
}

// ======== LEAF BORDER OVERLAY ========
function createLeafOverlay() {
    if (leafOverlay) return leafOverlay;

    const el = document.createElement('div');
    el.id = 'pidgey-leaf-overlay';
    el.setAttribute('style', `
    position: fixed!important;
    inset: 0!important;
    pointer-events: none!important;
    z-index: 2147483646!important;
    opacity: 0!important;
    transition: opacity 0.5s ease!important;
    box-shadow: inset 0 0 40px rgba(74, 222, 128, 0.5)!important;
    border: 4px solid rgba(74, 222, 128, 0.6)!important;
    box-sizing: border-box!important;
    `);

    const leaves = ['🍃', '🌿', '🍂', '🌱', '🍃', '🌿', '🍂', '🌱'];
    const positions = [
        { top: '8px', left: '10%' },
        { top: '4px', left: '30%' },
        { top: '10px', left: '50%' },
        { top: '6px', left: '70%' },
        { top: '20%', right: '8px' },
        { top: '50%', right: '4px' },
        { top: '80%', right: '10px' },
        { top: '40%', left: '6px' },
    ];

    positions.forEach((pos, i) => {
        const leaf = document.createElement('span');
        leaf.textContent = leaves[i % leaves.length];
        let style = `position: absolute!important; font-size: 20px!important; opacity: 0.7!important;
    animation: pidgey-sway ${2 + (i * 0.3)}s ease-in-out infinite!important;
    animation-delay: ${i * 0.15}s!important;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1))!important; `;
        for (const [key, value] of Object.entries(pos)) {
            style += `${key}: ${value} !important; `;
        }
        leaf.setAttribute('style', style);
        el.appendChild(leaf);
    });

    const styleSheet = document.createElement('style');
    styleSheet.textContent = `
    @keyframes pidgey-sway {
        0%, 100% { transform: rotate(-8deg) scale(1); }
        50% { transform: rotate(8deg) scale(1.1); }
    }
    `;
    el.appendChild(styleSheet);
    document.documentElement.appendChild(el);
    leafOverlay = el;
    return el;
}

function showLeaves() {
    const overlay = createLeafOverlay();
    overlay.style.setProperty('opacity', '1', 'important');
}

function hideLeaves() {
    if (leafOverlay) {
        leafOverlay.style.setProperty('opacity', '0', 'important');
    }
}

function querySelectorAllDeep(selector, root = document) {
    let results = Array.from(root.querySelectorAll(selector));
    for (const el of root.querySelectorAll('*')) {
        if (el.shadowRoot) {
            results = results.concat(querySelectorAllDeep(selector, el.shadowRoot));
        }
    }
    // Also check iframes for same-origin
    for (const iframe of root.querySelectorAll('iframe')) {
        try {
            const iDoc = iframe.contentDocument || iframe.contentWindow?.document;
            if (iDoc) results = results.concat(querySelectorAllDeep(selector, iDoc));
        } catch (e) { /* cross-origin iframe — skip */ }
    }
    return results;
}

// ======== PAGE INTERACTION (Sharper Beak) ========
function findElement(description) {
    const desc = description.toLowerCase();

    // Try common selectors based on description (including shadow piercing and contenteditable)
    const allInteractive = querySelectorAllDeep('button, a, input, textarea, select, [role="button"], [tabindex], [contenteditable="true"], [role="textbox"], [aria-label*="chat"], yt-formatted-string, ytcp-mention-textbox');

    // Score each element by how well it matches the description
    let bestMatch = null;
    let bestScore = 0;

    for (const el of allInteractive) {
        const text = (el.textContent || '').toLowerCase().trim();
        const ariaLabel = (el.getAttribute('aria-label') || '').toLowerCase();
        const placeholder = (el.getAttribute('placeholder') || '').toLowerCase();
        const title = (el.getAttribute('title') || '').toLowerCase();
        const name = (el.getAttribute('name') || '').toLowerCase();
        const id = (el.id || '').toLowerCase();
        const type = (el.getAttribute('type') || '').toLowerCase();

        let score = 0;

        // Exact text match
        if (text === desc) score += 100;
        else if (text.includes(desc)) score += 60;
        else if (desc.includes(text) && text.length > 2) score += 40;

        // Attribute matches
        if (ariaLabel.includes(desc) || desc.includes(ariaLabel)) score += 50;
        if (placeholder.includes(desc) || desc.includes(placeholder)) score += 50;
        if (title.includes(desc) || desc.includes(title)) score += 40;
        if (name.includes(desc) || desc.includes(name)) score += 30;
        if (id.includes(desc) || desc.includes(id)) score += 30;

        // Type-based matching
        if (desc.includes('search') && (type === 'search' || name.includes('search') || placeholder.includes('search'))) score += 70;
        if (desc.includes('submit') && type === 'submit') score += 70;
        if (desc.includes('login') && (text.includes('log') || text.includes('sign'))) score += 60;
        if (desc.includes('email') && (type === 'email' || name.includes('email'))) score += 60;
        if (desc.includes('password') && type === 'password') score += 60;

        // Visibility check
        const rect = el.getBoundingClientRect();
        if (rect.width === 0 || rect.height === 0) score -= 100;

        const pidgeyLabel = (el.getAttribute('data-pidgey-label') || '').toLowerCase();
        if (pidgeyLabel === desc || `[${pidgeyLabel}]` === desc || `${pidgeyLabel}` === desc.replace(/\[|\]/g, '')) score += 1000;

        if (score > bestScore) {
            bestScore = score;
            bestMatch = el;
        }
    }

    return bestMatch;
}

function handleInteraction(action, elementDesc, value, x, y) {
    return new Promise((resolve) => {
        let el = null;
        let usingCoordinates = false;

        // Prefer exact coordinate targeting if provided
        if (x !== undefined && y !== undefined) {
            // Adjust for device pixel ratio or scroll if necessary, but assume viewport coords for now
            el = document.elementFromPoint(x, y);
            usingCoordinates = true;
        }

        if (!el && elementDesc) {
            el = findElement(elementDesc);
        }

        if (!el) {
            if (usingCoordinates) return resolve(`Could not find any element at coordinates[${x}, ${y}]`);
            return resolve(`Could not find "${elementDesc}" on the page`);
        }

        const targetDesc = usingCoordinates ? `coordinates[${x}, ${y}]` : `"${elementDesc}"`;

        // =============================
        // FLY MASCOT TO ELEMENT
        // =============================
        const mascot = createPidgeyMascot();
        const rect = el.getBoundingClientRect();

        let targetX = rect.left + (rect.width / 2);
        let targetY = rect.top + (rect.height / 2);

        if (usingCoordinates) {
            targetX = x;
            targetY = y;
        }

        // Offset so Pidgey's beak hits the target
        targetX -= 15;
        targetY -= 50;

        // Ensure mascot is in coordinate mode
        mascot.style.setProperty('bottom', 'auto', 'important');
        mascot.style.setProperty('right', 'auto', 'important');
        mascot.style.setProperty('left', targetX + 'px', 'important');
        mascot.style.setProperty('top', targetY + 'px', 'important');

        // Wait for flight to finish (0.6s transit time) 
        setTimeout(() => {
            // Do peck animation
            mascot.style.setProperty('animation', 'none', 'important');
            void mascot.offsetWidth;
            mascot.style.setProperty('animation', 'pidgey-peck 0.4s ease-in-out', 'important');

            setTimeout(() => {
                mascot.style.setProperty('animation', 'pidgey-idle 3s ease-in-out infinite', 'important');

                switch (action.toLowerCase()) {
                    case 'click':
                        el.focus();
                        el.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, cancelable: true, view: window }));
                        el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, view: window }));
                        el.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, cancelable: true, view: window }));
                        el.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true, view: window }));
                        el.click();
                        const origOutline = el.style.outline;
                        el.style.outline = '3px solid #4ade80';
                        setTimeout(() => el.style.outline = origOutline, 1500);
                        resolve(`Clicked ${targetDesc} `);
                        break;

                    case 'type':
                        let targetForType = el;
                        const editableSelector = 'input, textarea, [contenteditable="true"], [contenteditable="plaintext-only"], [contenteditable=""], [contenteditable]';
                        
                        // Dive into the Shadow Root or children if the top element isn't directly typable
                        if (el.shadowRoot) {
                            const inner = el.shadowRoot.querySelector(editableSelector);
                            if (inner) targetForType = inner;
                        } else if (!el.isContentEditable && el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA') {
                            const inner = el.querySelector(editableSelector);
                            if (inner) targetForType = inner;
                        }

                        targetForType.focus();

                        // Fake a keydown to awaken reactive frameworks before populating
                        targetForType.dispatchEvent(new KeyboardEvent('keydown', { key: 'A', bubbles: true }));

                        if (targetForType.tagName === 'INPUT' || targetForType.tagName === 'TEXTAREA') {
                            const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
                            const nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value')?.set;

                            if (targetForType.tagName === 'INPUT' && nativeInputValueSetter) {
                                nativeInputValueSetter.call(targetForType, value);
                            } else if (targetForType.tagName === 'TEXTAREA' && nativeTextAreaValueSetter) {
                                nativeTextAreaValueSetter.call(targetForType, value);
                            } else {
                                targetForType.value = value;
                            }
                            
                            targetForType.dispatchEvent(new Event('input', { bubbles: true, composed: true, cancelable: true }));
                            targetForType.dispatchEvent(new Event('change', { bubbles: true, composed: true, cancelable: true }));
                            targetForType.dispatchEvent(new KeyboardEvent('keydown', { key: 'a', bubbles: true }));
                            targetForType.dispatchEvent(new KeyboardEvent('keyup', { key: 'a', bubbles: true }));
                            targetForType.dispatchEvent(new KeyboardEvent('keypress', { key: 'a', bubbles: true }));
                            targetForType.blur();
                        } else if (targetForType.isContentEditable || targetForType.hasAttribute('contenteditable')) {
                            targetForType.focus();
                            // document.execCommand FAILS across shadow root boundaries in modern Chrome.
                            // We directly manipulate textContent and simulate the InputEvent with Data.
                            targetForType.textContent = '';
                            targetForType.textContent = value;
                            
                            // For Polymer / ytcp elements, we MUST send a composed InputEvent
                            targetForType.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true, inputType: 'insertText', data: value }));
                            targetForType.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
                            targetForType.blur();
                        }

                        targetForType.style.outline = '3px solid #4ade80';
                        setTimeout(() => targetForType.style.outline = '', 1500);
                        resolve(`Typed "${value}" into ${targetDesc} `);
                        break;

                    case 'scroll':
                        el.scrollIntoView({ behavior: 'smooth', block: 'center' });
                        resolve(`Scrolled to ${targetDesc} `);
                        break;

                    case 'press_enter':
                        el.focus();
                        el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true, composed: true }));
                        el.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true, composed: true }));
                        resolve(`Pressed Enter on ${targetDesc} `);
                        break;

                    default:
                        resolve(`Unknown action: ${action} `);
                        break;
                }
            }, 300); // 300ms for peck to hit the button
        }, 650); // 650ms for flight transit
    });
}

// ======== SCRAPE PAGE (Swoop & Scrape) ========
function scrapePage(dataType) {
    switch (dataType.toLowerCase()) {
        case 'links': {
            const links = [...document.querySelectorAll('a[href]')]
                .filter(a => a.href && !a.href.startsWith('javascript'))
                .slice(0, 30)
                .map(a => `- [${(a.textContent || '').trim().slice(0, 60) || a.href}](${a.href})`);
            return links.join('\n') || 'No links found';
        }

        case 'images': {
            const imgs = [...document.querySelectorAll('img[src]')]
                .slice(0, 20)
                .map(img => `- ${img.alt || 'image'}: ${img.src} `);
            return imgs.join('\n') || 'No images found';
        }

        case 'text': {
            // Using a disconnected clone with .innerText often fails in Chromium because it lacks a layout tree.
            // Sites like TradingView, secure portals, and heavy SPAs will return empty strings.
            // We use the live document.body.innerText, and fallback to textContent.
            let text = document.body.innerText || '';
            if (!text || text.trim() === '') text = document.body.textContent || '';

            // Clean up heavy whitespace and increase extraction limit slightly to account for missing junk filters
            text = text.replace(/\n\s*\n/g, '\n').slice(0, 8000);
            return text || 'No text content found';
        }

        case 'prices': {
            const priceRegex = /\$[\d,]+\.?\d*/g;
            const text = document.body.innerText;
            const prices = [...new Set(text.match(priceRegex) || [])].slice(0, 20);
            return prices.length > 0 ? prices.map(p => `- ${p} `).join('\n') : 'No prices found';
        }

        case 'forms': {
            const fields = collectAllFields(document);
            if (!fields.length) return 'No form fields found on this page.';
            const report = fields.map((el, i) => {
                const name = el.name || el.id || '';
                const placeholder = el.getAttribute('placeholder') || '';
                const type = el.getAttribute('type') || el.tagName.toLowerCase();
                let labelText = '';
                if (el.id) {
                    const lbl = document.querySelector(`label[for="${el.id}"]`);
                    if (lbl) labelText = lbl.textContent.trim();
                }
                const pidgeyLabel = el.getAttribute('data-pidgey-label') || '';
                return `[Field ${i + 1}] Type: ${type} | Name/ID: "${name}" | Placeholder: "${placeholder}" | Label: "${labelText}" | VisionTag: "${pidgeyLabel}"`;
            }).slice(0, 40).join('\n');
            return report;
        }

        default: {
            // Generic: return page title + first 2000 chars
            return `** ${document.title}**\n\n${document.body.innerText.slice(0, 2000)} `;
        }
    }
}

// ======== AUTOFILL FORM — Pidgey Patch v2 ========
// Shadow DOM aware, label-matching, native-setter, React/Vue compatible

/** Collect ALL input/textarea/select from document + shadow roots + iframes */
function collectAllFields(root = document) {
    const fields = [];
    const selector = 'input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]), textarea, select, [contenteditable="true"], [contenteditable=""], [contenteditable], [role="textbox"], ytcp-social-suggestions-textbox, ytcp-mention-textbox, yt-formatted-string';

    // Direct fields
    fields.push(...root.querySelectorAll(selector));

    // Shadow DOM roots
    root.querySelectorAll('*').forEach(el => {
        if (el.shadowRoot) fields.push(...collectAllFields(el.shadowRoot));
    });

    // Iframes (same-origin only, cross-origin will silently fail)
    root.querySelectorAll('iframe').forEach(iframe => {
        try {
            const iDoc = iframe.contentDocument || iframe.contentWindow?.document;
            if (iDoc) fields.push(...collectAllFields(iDoc));
        } catch (e) { /* cross-origin iframe — skip */ }
    });

    return fields;
}

/** Score how well a field matches the target key */
function scoreField(el, key) {
    const k = key.toLowerCase();
    let score = 0;

    const attrs = {
        name: (el.getAttribute('name') || '').toLowerCase(),
        id: (el.id || '').toLowerCase(),
        placeholder: (el.getAttribute('placeholder') || '').toLowerCase(),
        ariaLabel: (el.getAttribute('aria-label') || '').toLowerCase(),
        ariaDescBy: (el.getAttribute('aria-describedby') || '').toLowerCase(),
        type: (el.getAttribute('type') || '').toLowerCase(),
        className: (el.className || '').toLowerCase(),
    };

    // Get associated <label> text
    let labelText = '';
    if (el.id) {
        const lbl = document.querySelector(`label[for="${el.id}"]`);
        if (lbl) labelText = lbl.textContent.toLowerCase().trim();
    }
    if (!labelText) {
        const parent = el.closest('label, .form-group, .field, [class*="field"], [class*="row"]');
        if (parent) labelText = parent.textContent.toLowerCase().trim().slice(0, 80);
    }

    // Pidgey Vision Labels
    const pidgeyLabel = (el.getAttribute('data-pidgey-label') || '').toLowerCase();
    if (pidgeyLabel === k || `[${pidgeyLabel}]` === k || pidgeyLabel === k.replace(/\[|\]/g, '')) score += 1000;

    // Exact matches
    if (attrs.name === k || attrs.id === k) score += 100;
    if (attrs.placeholder === k || attrs.ariaLabel === k) score += 90;
    if (labelText === k) score += 95;

    // Partial matches
    Object.values(attrs).forEach(v => { if (v.includes(k) || k.includes(v) && v.length > 2) score += 40; });
    if (labelText.includes(k) || k.includes(labelText) && labelText.length > 2) score += 50;

    // Type-based bonus
    if (k.includes('email') && attrs.type === 'email') score += 30;
    if (k.includes('phone') && (attrs.type === 'tel' || attrs.name.includes('phone'))) score += 30;
    if (k.includes('pass') && attrs.type === 'password') score += 30;
    if (k.includes('name') && attrs.type === 'text') score += 10;

    // Visibility penalty
    const rect = el.getBoundingClientRect();
    if (rect.width === 0 && rect.height === 0) score -= 50;

    return score;
}

/** Set a field value using native descriptors to bypass React/Vue state */
function setFieldValue(el, value) {
    el.focus();
    el.scrollIntoView({ behavior: 'smooth', block: 'center' });

    if (el.tagName === 'SELECT') {
        // Match by option text or value
        const opts = [...el.options];
        const match = opts.find(o => o.value.toLowerCase() === value.toLowerCase() || o.text.toLowerCase().includes(value.toLowerCase()));
        if (match) {
            el.value = match.value;
            el.dispatchEvent(new Event('change', { bubbles: true }));
            return true;
        }
        return false;
    }

    if (el.type === 'checkbox' || el.type === 'radio') {
        const shouldCheck = ['true', '1', 'yes', 'on', 'check'].includes(value.toLowerCase());
        el.checked = shouldCheck;
        el.dispatchEvent(new Event('change', { bubbles: true }));
        el.dispatchEvent(new Event('click', { bubbles: true }));
        return true;
    }

    let targetForType = el;
    const editableSelector = 'input, textarea, [contenteditable="true"], [contenteditable="plaintext-only"], [contenteditable=""], [contenteditable]';
    
    // Dive into the Shadow Root or children if the top element isn't directly typable
    if (el.shadowRoot) {
        const inner = el.shadowRoot.querySelector(editableSelector);
        if (inner) targetForType = inner;
    } else if (!el.isContentEditable && el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA') {
        const inner = el.querySelector(editableSelector);
        if (inner) targetForType = inner;
    }

    if (targetForType.tagName === 'INPUT' || targetForType.tagName === 'TEXTAREA') {
        // Use native descriptor to bypass React/Vue synthetic events
        try {
            const proto = targetForType.tagName === 'INPUT' ? window.HTMLInputElement.prototype : window.HTMLTextAreaElement.prototype;
            const nativeSetter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
            if (nativeSetter) {
                nativeSetter.call(targetForType, value);
            } else {
                targetForType.value = value;
            }
        } catch (e) {
            targetForType.value = value;
        }

        // Fire full event suite for React, Vue, Angular, Svelte compatibility
        targetForType.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
        targetForType.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
        targetForType.dispatchEvent(new KeyboardEvent('keydown', { key: 'a', bubbles: true }));
        targetForType.dispatchEvent(new KeyboardEvent('keyup', { key: 'a', bubbles: true }));
        targetForType.dispatchEvent(new KeyboardEvent('keypress', { key: 'a', bubbles: true }));
        targetForType.blur();

        // Visual confirm
        targetForType.style.outline = '3px solid #4ade80';
        targetForType.style.transition = 'outline 0.3s ease';
        setTimeout(() => { targetForType.style.outline = ''; targetForType.style.transition = ''; }, 2000);
        return true;
    } else if (targetForType.isContentEditable || targetForType.hasAttribute('contenteditable') || targetForType.getAttribute('contenteditable') === 'true') {
        targetForType.focus();
        targetForType.textContent = '';
        targetForType.textContent = value;
        
        targetForType.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true, inputType: 'insertText', data: value }));
        targetForType.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
        targetForType.blur();
        
        // Visual confirm
        targetForType.style.outline = '3px solid #4ade80';
        targetForType.style.transition = 'outline 0.3s ease';
        setTimeout(() => { targetForType.style.outline = ''; targetForType.style.transition = ''; }, 2000);
        return true;
    }

    return false;
}

function autofillForm(formData) {
    const allFields = collectAllFields();
    const results = [];
    let filled = 0;

    for (const [key, value] of Object.entries(formData)) {
        // Score all fields and pick best match
        let best = null;
        let bestScore = 0;

        for (const el of allFields) {
            const s = scoreField(el, key);
            if (s > bestScore) { bestScore = s; best = el; }
        }

        if (best && bestScore > 20) {
            const ok = setFieldValue(best, value);
            if (ok) {
                filled++;
                results.push(`✅ "${key}" → filled (score ${bestScore})`);
            } else {
                results.push(`⚠️ "${key}" → found but fill failed (select/type mismatch?)`);
            }
        } else {
            results.push(`❌ "${key}" → no matching field found (best score: ${bestScore})`);
        }
    }

    return `Filled ${filled}/${Object.keys(formData).length} fields:\n${results.join('\n')}`;
}

// ======== MESSAGE HANDLER ========
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
    // Make sure mascot is on screen as soon as background tries to talk to us
    createPidgeyMascot();

    // Probe message — used by sidepanel to check if content script is alive
    if (msg.type === 'PIDGEY_PING') {
        sendResponse('pong');
        return true;
    }

    if (msg.type === 'PIDGEY_STATE') {
        if (msg.state === 'thinking') {
            showLeaves();
            setMascotState('thinking');
        } else {
            hideLeaves();
            setMascotState('idle');
        }
        return;
    }

    if (msg.type === 'PIDGEY_ACTION') {
        handleInteraction(msg.action, msg.element, msg.value, msg.x, msg.y).then(result => {
            sendResponse(result);
        });
        return true;
    }

    if (msg.type === 'PIDGEY_SCRAPE') {
        const result = scrapePage(msg.dataType);
        sendResponse(result);
        return true;
    }

    if (msg.type === 'PIDGEY_AUTOFILL') {
        const result = autofillForm(msg.formData || {});
        sendResponse(result);
        return true;
    }

    if (msg.type === 'PIDGEY_DRAW_LABELS') {
        drawBoundingBoxes();
        sendResponse('Labels drawn');
        return true;
    }

    if (msg.type === 'PIDGEY_CLEAR_LABELS') {
        clearBoundingBoxes();
        sendResponse('Labels cleared');
        return true;
    }

    if (msg.type === 'PIDGEY_HIGHLIGHT') {
        highlightScreenElements(msg.x, msg.y, msg.width, msg.height, msg.color, msg.text);
        sendResponse('Highlight drawn');
        return true;
    }

    if (msg.type === 'PIDGEY_CLEAR_HIGHLIGHTS') {
        clearHighlights();
        sendResponse('Highlights cleared');
        return true;
    }

    if (msg.type === 'PIDGEY_MONITOR') {
        const targetDesc = msg.targetElement;
        const op = msg.condition_operator;
        let val = msg.condition_value;

        // Auto-parse numeric values if applicable
        const numVal = parseFloat(val?.replace(/[^0-9.-]+/g, ""));

        const interval = setInterval(() => {
            const el = findElement(targetDesc);
            if (!el) return;
            const text = (el.textContent || '').trim();
            if (!text) return;

            let conditionMet = false;

            // Clean text for numeric comparison
            const numText = parseFloat(text.replace(/[^0-9.-]+/g, ""));

            switch (op) {
                case '<': conditionMet = (!isNaN(numText) && !isNaN(numVal) && numText < numVal); break;
                case '>': conditionMet = (!isNaN(numText) && !isNaN(numVal) && numText > numVal); break;
                case '==': conditionMet = (text === val || (!isNaN(numText) && !isNaN(numVal) && numText === numVal)); break;
                case '!=': conditionMet = (text !== val && (!isNaN(numText) && !isNaN(numVal) && numText !== numVal)); break;
                case 'includes': conditionMet = text.toLowerCase().includes(val.toLowerCase()); break;
                case 'not_includes': conditionMet = !text.toLowerCase().includes(val.toLowerCase()); break;
            }

            if (conditionMet) {
                clearInterval(interval);
                chrome.runtime.sendMessage({
                    type: 'PIDGEY_MONITOR_ALERT',
                    message: `Target "${targetDesc}" triggered!\nCurrent value: ${text}`
                });

                if (msg.actionElement && msg.actionElement.trim().toLowerCase() !== 'none') {
                    handleInteraction('click', msg.actionElement, msg.actionValue).then(() => { });
                }
            }
        }, 1500);

        sendResponse('Monitor started (Secure Mode)');
        return true;
    }
});

let labelOverlays = [];
let highlightOverlays = [];

function highlightScreenElements(x, y, w, h, color = '#3b82f6', text = '') {
    const highlight = document.createElement('div');
    highlight.setAttribute('style', `
        position: fixed !important;
        top: ${y}px !important;
        left: ${x}px !important;
        width: ${w}px !important;
        height: ${h}px !important;
        border: 4px solid var(--pidgey-highlight-color) !important;
        border-radius: 8px !important;
        pointer-events: none !important;
        z-index: 2147483647 !important;
        box-shadow: 0 0 15px var(--pidgey-highlight-color), inset 0 0 10px var(--pidgey-highlight-color) !important;
        background-color: color-mix(in sRGB, var(--pidgey-highlight-color) 20%, transparent) !important;
        transition: all 0.3s ease !important;
        animation: pidgey-pulse-highlight 2s infinite !important;
        --pidgey-highlight-color: ${color};
    `);

    if (text) {
        const textLabel = document.createElement('div');
        textLabel.textContent = text;
        textLabel.setAttribute('style', `
            position: absolute !important;
            top: -30px !important;
            left: 50% !important;
            transform: translateX(-50%) !important;
            background: ${color} !important;
            color: white !important;
            padding: 4px 12px !important;
            border-radius: 12px !important;
            font-size: 14px !important;
            font-weight: bold !important;
            white-space: nowrap !important;
            box-shadow: 0 2px 8px rgba(0,0,0,0.3) !important;
            font-family: system-ui, sans-serif !important;
        `);
        highlight.appendChild(textLabel);
    }

    // Add pulsing css if not exists
    if (!document.getElementById('pidgey-highlight-styles')) {
        const styleSheet = document.createElement('style');
        styleSheet.id = 'pidgey-highlight-styles';
        styleSheet.textContent = `
          @keyframes pidgey-pulse-highlight {
            0% { box-shadow: 0 0 15px var(--pidgey-highlight-color), inset 0 0 10px var(--pidgey-highlight-color); }
            50% { box-shadow: 0 0 25px var(--pidgey-highlight-color), inset 0 0 20px var(--pidgey-highlight-color); transform: scale(1.02); }
            100% { box-shadow: 0 0 15px var(--pidgey-highlight-color), inset 0 0 10px var(--pidgey-highlight-color); }
          }
        `;
        document.documentElement.appendChild(styleSheet);
    }

    document.documentElement.appendChild(highlight);
    highlightOverlays.push(highlight);
}

function clearHighlights() {
    highlightOverlays.forEach(el => el.remove());
    highlightOverlays = [];
}

function drawBoundingBoxes() {
    clearBoundingBoxes();
    const interactables = querySelectorAllDeep('button, a[href], input, select, textarea, [role="button"], [tabindex], [contenteditable="true"], [role="textbox"], yt-formatted-string, ytcp-mention-textbox');
    let labelIndex = 0;

    interactables.forEach(el => {
        const rect = el.getBoundingClientRect();
        // Skip hidden or off-screen elements
        if (rect.width === 0 || rect.height === 0 || rect.top < 0 || rect.left < 0 || rect.bottom > window.innerHeight || rect.right > window.innerWidth) return;

        // Skip elements that are fully obscured
        const topEl = document.elementFromPoint(rect.left + rect.width / 2, rect.top + rect.height / 2);
        if (topEl && !el.contains(topEl) && !topEl.contains(el)) {
           // It's technically covered, but we might still want to label it. For now, we'll just not filter here.
        }

        let charStr = "";
        let n = labelIndex;
        while (n >= 0) {
            charStr = String.fromCharCode(65 + (n % 26)) + charStr;
            n = Math.floor(n / 26) - 1;
        }

        const label = document.createElement('div');
        label.textContent = charStr;
        label.className = 'pidgey-bounding-box-label';
        label.setAttribute('style', `
            position: fixed !important;
            top: ${rect.top}px !important;
            left: ${rect.left}px !important;
            background: #ef4444 !important;
            color: white !important;
            font-size: 11px !important;
            font-weight: 900 !important;
            padding: 2px 4px !important;
            z-index: 2147483647 !important;
            pointer-events: none !important;
            border-radius: 3px !important;
            border: 1px solid white !important;
            box-shadow: 0 0 4px rgba(0,0,0,0.5) !important;
            font-family: monospace !important;
            line-height: 1 !important;
        `);
        document.documentElement.appendChild(label);
        labelOverlays.push(label);

        el.setAttribute('data-pidgey-label', charStr);
        labelIndex++;
    });
}

function clearBoundingBoxes() {
    labelOverlays.forEach(el => el.remove());
    labelOverlays = [];
}
