"""Anti-detection and stealth functionality."""

import random
from typing import Optional


class StealthConfig:
    """Configuration for stealth mode."""
    
    def __init__(
        self,
        hide_webdriver: bool = True,
        fake_plugins: bool = True,
        fake_languages: bool = True,
        random_viewport: bool = True,
        random_user_agent: bool = False,
    ):
        self.hide_webdriver = hide_webdriver
        self.fake_plugins = fake_plugins
        self.fake_languages = fake_languages
        self.random_viewport = random_viewport
        self.random_user_agent = random_user_agent


# Common user agents
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15",
]

# Common viewports
VIEWPORTS = [
    {"width": 1920, "height": 1080},
    {"width": 1366, "height": 768},
    {"width": 1440, "height": 900},
    {"width": 1536, "height": 864},
    {"width": 1280, "height": 720},
]


def get_stealth_scripts(config: Optional[StealthConfig] = None) -> list[str]:
    """
    Get stealth scripts to inject into page.
    
    Args:
        config: Stealth configuration
        
    Returns:
        List of JavaScript scripts to inject
    """
    if config is None:
        config = StealthConfig()
    
    scripts = []
    
    if config.hide_webdriver:
        scripts.append("""
            // Hide webdriver
            Object.defineProperty(navigator, 'webdriver', {
                get: () => undefined
            });
            
            // Hide automation flags
            delete navigator.__proto__.webdriver;
            
            // Override permissions
            const originalQuery = window.navigator.permissions.query;
            window.navigator.permissions.query = (parameters) => (
                parameters.name === 'notifications' 
                    ? Promise.resolve({ state: Notification.permission })
                    : originalQuery(parameters)
            );
        """)
    
    if config.fake_plugins:
        scripts.append("""
            // Fake plugins
            Object.defineProperty(navigator, 'plugins', {
                get: () => [
                    {name: "Chrome PDF Plugin", filename: "internal-pdf-viewer"},
                    {name: "Chrome PDF Viewer", filename: "mhjfbmdgcfjbbpaeojofohoefgiehjai"},
                    {name: "Native Client", filename: "internal-nacl-plugin"},
                ]
            });
        """)
    
    if config.fake_languages:
        scripts.append("""
            // Fake languages
            Object.defineProperty(navigator, 'languages', {
                get: () => ['zh-CN', 'zh', 'en-US', 'en']
            });
            Object.defineProperty(navigator, 'language', {
                get: () => 'zh-CN'
            });
        """)
    
    # Hide Playwright-specific properties
    scripts.append("""
        // Hide Playwright
        delete window.__playwright;
        delete window.__pw_manual;
        delete window.__PW_inspect;
    """)
    
    # Override console to hide automation messages
    scripts.append("""
        // Override console
        const originalConsoleLog = console.log;
        console.log = function(...args) {
            if (args.length > 0 && typeof args[0] === 'string') {
                if (args[0].includes('playwright') || args[0].includes('automation')) {
                    return;
                }
            }
            originalConsoleLog.apply(console, args);
        };
    """)
    
    return scripts


def get_random_user_agent() -> str:
    """Get a random user agent."""
    return random.choice(USER_AGENTS)


def get_random_viewport() -> dict:
    """Get a random viewport size."""
    return random.choice(VIEWPORTS)


def get_stealth_args() -> list[str]:
    """
    Get Chrome arguments for stealth mode.
    
    Returns:
        List of Chrome command-line arguments
    """
    return [
        "--disable-blink-features=AutomationControlled",
        "--disable-web-security",
        "--disable-features=IsolateOrigins,site-per-process",
        "--disable-site-isolation-trials",
        "--disable-features=BlockInsecurePrivateNetworkRequests",
        "--disable-infobars",
        "--disable-dev-shm-usage",
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-gpu",
        "--disable-software-rasterizer",
        "--disable-extensions",
        "--disable-default-apps",
        "--disable-background-networking",
        "--disable-background-timer-throttling",
        "--disable-backgrounding-occluded-windows",
        "--disable-breakpad",
        "--disable-component-update",
        "--disable-domain-reliability",
        "--disable-features=AudioServiceOutOfProcess",
        "--disable-features=TranslateUI",
        "--disable-hang-monitor",
        "--disable-ipc-flooding-protection",
        "--disable-popup-blocking",
        "--disable-prompt-on-repost",
        "--disable-renderer-backgrounding",
        "--force-color-profile=srgb",
        "--metrics-recording-only",
        "--safebrowsing-disable-auto-update",
    ]


class CloudflareBypass:
    """Helper class for bypassing Cloudflare protection."""
    
    @staticmethod
    async def wait_for_challenge(page) -> bool:
        """
        Wait for Cloudflare challenge to complete.
        
        Args:
            page: Playwright page object
            
        Returns:
            True if challenge passed, False otherwise
        """
        try:
            # Check for Cloudflare challenge
            challenge_selectors = [
                "#cf-challenge-running",
                ".cf-browser-verification",
                "#cf-please-wait",
                "#challenge-form",
            ]
            
            for selector in challenge_selectors:
                try:
                    await page.wait_for_selector(selector, timeout=5000)
                    print(f"⚠️  检测到 Cloudflare 验证，等待中...")
                    
                    # Wait for challenge to complete
                    await page.wait_for_selector(selector, state="detached", timeout=30000)
                    print(f"✅ Cloudflare 验证通过")
                    return True
                except:
                    continue
            
            return False
        except Exception as e:
            print(f"❌ Cloudflare 验证出错: {e}")
            return False
    
    @staticmethod
    def is_cloudflare_page(content: str) -> bool:
        """Check if page content indicates Cloudflare protection."""
        cloudflare_markers = [
            "cf-browser-verification",
            "cf-challenge-running",
            "Checking your browser",
            "DDoS protection by Cloudflare",
        ]
        return any(marker in content for marker in cloudflare_markers)


class FingerprintRandomizer:
    """Randomize browser fingerprint."""
    
    @staticmethod
    def get_random_fingerprint() -> dict:
        """Get a random browser fingerprint."""
        return {
            "user_agent": get_random_user_agent(),
            "viewport": get_random_viewport(),
            "color_depth": random.choice([24, 32]),
            "pixel_ratio": random.choice([1, 1.25, 1.5, 2]),
            "timezone": random.choice(["Asia/Shanghai", "Asia/Tokyo", "America/New_York"]),
        }
