// Browser API polyfill for cross-browser compatibility
(function() {
    'use strict';
    
    // Define browser polyfill in the global scope (works in both service workers and content scripts)
    if (typeof browser === 'undefined' && typeof chrome !== 'undefined') {
        // Use self (service worker) or window (content script) or global fallback
        const globalScope = (function() {
            if (typeof self !== 'undefined') return self;
            if (typeof window !== 'undefined') return window;
            if (typeof global !== 'undefined') return global;
            return this;
        })();
        
        globalScope.browser = chrome;
    }
})();

(function(browser) {
    let settings = {
        linkBehavior: 'disabled',
        domainMatching: 'base',
        modifierKeys: {
            cmd: false,
            shift: false,
            alt: false,
            ctrl: false
        },
        respectTargetBlank: true
    };
    let currentDomain = '';
    let currentBaseDomain = '';
    let isInitialized = false;
    let clickHandler = null; // Track the current click handler
    let lastClickTime = 0;
    let lastClickUrl = '';
    const CLICK_DEBOUNCE_MS = 500; // Prevent multiple clicks within 500ms

    // Get current domain and base domain
    function getCurrentDomains() {
        try {
            const url = new URL(window.location.href);
            currentDomain = url.hostname;
            currentBaseDomain = extractBaseDomain(currentDomain);
            return { currentDomain, currentBaseDomain };
        } catch (e) {
            return { currentDomain: '', currentBaseDomain: '' };
        }
    }

    // Extract base domain (e.g., "google.com" from "www.google.com" or "accounts.google.com")
    function extractBaseDomain(hostname) {
        if (!hostname) return '';
        
        // Remove 'www.' prefix if present
        const withoutWww = hostname.replace(/^www\./, '');
        
        // Split by dots
        const parts = withoutWww.split('.');
        
        // If it's already a base domain (like "google.com"), return as-is
        if (parts.length <= 2) {
            return withoutWww;
        }
        
        // For longer domains, take the last two parts (domain.tld)
        // This handles cases like "accounts.google.com" -> "google.com"
        // But preserves cases like "github.io" or "co.uk" domains
        
        // Common two-part TLDs that should be preserved
        const twoPartTlds = [
            'co.uk', 'co.jp', 'co.za', 'com.au', 'com.br', 'com.cn',
            'com.mx', 'co.in', 'co.kr', 'com.tw', 'com.sg', 'com.my',
            'co.nz', 'co.th', 'com.ar', 'com.co', 'com.pe', 'com.ve',
            'org.uk', 'net.au', 'gov.uk', 'edu.au', 'ac.uk'
        ];
        
        const lastTwoParts = parts.slice(-2).join('.');
        const lastThreeParts = parts.length >= 3 ? parts.slice(-3).join('.') : '';
        
        // Check if the last three parts form a known two-part TLD
        if (lastThreeParts && twoPartTlds.includes(parts.slice(-2).join('.'))) {
            return lastThreeParts;
        }
        
        return lastTwoParts;
    }

    // Check if URL is external based on current domain matching setting
    function isExternalLink(url) {
        try {
            const linkUrl = new URL(url, window.location.href);
            const linkDomain = linkUrl.hostname;
            const linkBaseDomain = extractBaseDomain(linkDomain);
            
            // If domains are empty, it's not external
            if (!currentDomain || !linkDomain) {
                return false;
            }
            
            switch (settings.domainMatching) {
                case 'exact':
                    return linkDomain !== currentDomain;
                    
                case 'base':
                    return linkBaseDomain !== currentBaseDomain;
                    
                case 'subdomain':
                    // Check if both domains share the same base domain (excluding www)
                    const currentWithoutWww = currentDomain.replace(/^www\./, '');
                    const linkWithoutWww = linkDomain.replace(/^www\./, '');
                    
                    // If one is a subdomain of the other, they're considered same domain
                    return !currentWithoutWww.endsWith('.' + linkBaseDomain) && 
                           !linkWithoutWww.endsWith('.' + currentBaseDomain) &&
                           linkBaseDomain !== currentBaseDomain;
                           
                default:
                    return linkBaseDomain !== currentBaseDomain;
            }
        } catch (e) {
            console.log("OpenIn: Error checking if link is external:", e);
            return false;
        }
    }

    // Check if URL is HTTP/HTTPS (only protocols we handle)
    function isHttpUrl(url) {
        try {
            const urlObj = new URL(url, window.location.href);
            return urlObj.protocol === 'http:' || urlObj.protocol === 'https:';
        } catch (e) {
            return false;
        }
    }

    // Check if modifier keys match the configured combination
    function modifierKeysMatch(event) {
        if (settings.linkBehavior !== 'modifier') {
            return false;
        }
        
        const required = settings.modifierKeys;
        const pressed = {
            cmd: event.metaKey,
            shift: event.shiftKey,
            alt: event.altKey,
            ctrl: event.ctrlKey
        };
        
        // Check if all required modifier keys are pressed and no extra ones
        return Object.keys(required).every(key => {
            return required[key] === pressed[key];
        });
    }

    // Check if link should be intercepted based on current settings
    function shouldInterceptLink(link, event) {
        // Skip if link or href is missing
        if (!link || !link.href) {
            return false;
        }
        
        // Only handle HTTP/HTTPS URLs
        if (!isHttpUrl(link.href)) {
            return false;
        }
        
        // Skip if not an external link
        if (!isExternalLink(link.href)) {
            return false;
        }
        
        // Skip if target="_blank" and we're configured to respect it
        if (settings.respectTargetBlank && 
            (link.target === '_blank' || link.target === '_new')) {
            console.log("OpenIn: Respecting target=_blank for:", link.href);
            return false;
        }
        
        // Check behavior setting
        switch (settings.linkBehavior) {
            case 'disabled':
                return false;
                
            case 'automatic':
                // Don't intercept if any modifier keys are pressed (user wants browser behavior)
                return !(event.ctrlKey || event.metaKey || event.shiftKey || event.altKey);
                
            case 'modifier':
                return modifierKeysMatch(event);
                
            default:
                return false;
        }
    }

    // Set up link interception
    function setupLinkInterception() {
        if (!isInitialized) return;
        
        console.log("OpenIn: Setting up link interception with settings:", settings);
        
        // Remove previous event listener if it exists
        if (clickHandler) {
            document.removeEventListener('click', clickHandler, true);
            clickHandler = null;
        }
        
        // Create new click handler
        clickHandler = (event) => {
            const link = event.target.closest('a');
            
            if (!shouldInterceptLink(link, event)) {
                return;
            }
            
            // Debounce rapid clicks on the same URL
            const now = Date.now();
            if (now - lastClickTime < CLICK_DEBOUNCE_MS && lastClickUrl === link.href) {
                console.log("OpenIn: Ignoring rapid duplicate click on:", link.href);
                event.preventDefault();
                event.stopPropagation();
                return;
            }
            
            lastClickTime = now;
            lastClickUrl = link.href;
            
            console.log("OpenIn: Intercepting link click:", {
                href: link ? link.href : 'unknown',
                behavior: settings ? settings.linkBehavior : 'unknown',
                domainMatching: settings ? settings.domainMatching : 'unknown',
                modifierKeys: event ? {
                    cmd: event.metaKey || false,
                    shift: event.shiftKey || false,
                    alt: event.altKey || false,
                    ctrl: event.ctrlKey || false
                } : {}
            });
            
            // Prevent default navigation
            event.preventDefault();
            event.stopPropagation();
            
            // Send to OpenIn app with additional tab context
            try {
                if (!browser || !browser.runtime || !browser.runtime.sendMessage) {
                    console.log("OpenIn: Browser runtime not available, navigating normally");
                    window.location.href = link.href;
                    return;
                }
                
                const message = browser.runtime.sendMessage({
                    action: "openInApp",
                    url: link.href,
                    source: "link",
                    fromContentScript: true
                });
                
                if (message && typeof message.then === 'function') {
                    // Promise-based API
                    message.then((response) => {
                        if (response && response.success) {
                            console.log("OpenIn: Successfully sent link to app");
                        } else {
                            console.log("OpenIn: Failed to send link to app, navigating normally");
                            window.location.href = link.href;
                        }
                    }).catch((error) => {
                        console.log("OpenIn: Error sending message to extension:", error);
                        window.location.href = link.href;
                    });
                } else {
                    // Callback-based API fallback
                    console.log("OpenIn: Message sent (callback-based API)");
                }
            } catch (error) {
                console.log("OpenIn: Exception in browser messaging:", error);
                window.location.href = link.href;
            }
        };
        
        // Add the new event listener
        document.addEventListener('click', clickHandler, true); // Use capture phase to catch events early
    }

    // Initialize content script
    function init() {
        const domains = getCurrentDomains();
        currentDomain = domains.currentDomain;
        currentBaseDomain = domains.currentBaseDomain;
        
        console.log("OpenIn: Content script initializing:", {
            currentDomain,
            currentBaseDomain,
            url: window.location.href
        });
        
        // Get settings from background script
        browser.runtime.sendMessage({ action: "getSettings" }).then((response) => {
            if (response) {
                // Update settings with response, keeping defaults for missing values
                settings = {
                    linkBehavior: response.linkBehavior || settings.linkBehavior,
                    domainMatching: response.domainMatching || settings.domainMatching,
                    modifierKeys: response.modifierKeys || settings.modifierKeys,
                    respectTargetBlank: response.respectTargetBlank !== undefined ? response.respectTargetBlank : settings.respectTargetBlank
                };
                
                console.log("OpenIn: Loaded settings:", settings);
                isInitialized = true;
                setupLinkInterception();
            }
        }).catch((error) => {
            console.log("OpenIn: Could not get settings, using defaults:", error);
            isInitialized = true;
            setupLinkInterception();
        });
    }

    // Listen for settings changes from options page
    browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
        if (message.action === "settingsChanged" && message.settings) {
            console.log("OpenIn: Settings changed:", message.settings);
            settings = { ...settings, ...message.settings };
            
            // Re-setup interception with new settings (this will remove old listener first)
            setupLinkInterception();
        }
    });

    // Initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})(typeof browser !== 'undefined' ? browser : chrome);