"""
CFspider 浏览器模块
基于 Playwright 封装，支持通过 Cloudflare Workers 代理
"""

from .local_proxy import LocalProxyServer

try:
    from playwright.sync_api import sync_playwright, Page, Browser as PlaywrightBrowser
    PLAYWRIGHT_AVAILABLE = True
except ImportError:
    PLAYWRIGHT_AVAILABLE = False
    Page = None
    PlaywrightBrowser = None


class BrowserNotInstalledError(Exception):
    """浏览器未安装错误"""
    pass


class PlaywrightNotInstalledError(Exception):
    """Playwright 未安装错误"""
    pass


class Browser:
    """
    CFspider 浏览器类
    
    封装 Playwright，通过 Cloudflare Workers 代理浏览器流量
    
    Example:
        >>> import cfspider
        >>> browser = cfspider.Browser(cf_proxies="https://ip.kami666.xyz")
        >>> html = browser.html("https://example.com")
        >>> browser.close()
    """
    
    def __init__(self, cf_proxies, headless=True, timeout=30):
        """
        初始化浏览器
        
        Args:
            cf_proxies: Workers 地址，如 "https://ip.kami666.xyz"
            headless: 是否无头模式，默认 True
            timeout: 请求超时时间（秒），默认 30
        """
        if not PLAYWRIGHT_AVAILABLE:
            raise PlaywrightNotInstalledError(
                "Playwright 未安装，请运行: pip install playwright"
            )
        
        self.cf_proxies = cf_proxies
        self.headless = headless
        self.timeout = timeout
        
        # 启动本地代理服务器
        self._proxy_server = LocalProxyServer(cf_proxies, timeout)
        self._proxy_port = self._proxy_server.start()
        
        # 启动 Playwright
        self._playwright = sync_playwright().start()
        
        # 启动浏览器
        try:
            self._browser = self._playwright.chromium.launch(
                headless=headless,
                proxy={
                    "server": f"http://127.0.0.1:{self._proxy_port}"
                }
            )
        except Exception as e:
            self._proxy_server.stop()
            self._playwright.stop()
            if "Executable doesn't exist" in str(e):
                raise BrowserNotInstalledError(
                    "Chromium 浏览器未安装，请运行: cfspider install"
                )
            raise
        
        # 创建默认上下文
        self._context = self._browser.new_context(
            ignore_https_errors=True
        )
        self._context.set_default_timeout(timeout * 1000)
    
    def get(self, url):
        """
        打开页面并返回 Page 对象
        
        Args:
            url: 目标 URL
            
        Returns:
            Page: Playwright Page 对象，可用于自动化操作
        """
        page = self._context.new_page()
        page.goto(url, wait_until="networkidle")
        return page
    
    def html(self, url):
        """
        获取页面渲染后的 HTML
        
        Args:
            url: 目标 URL
            
        Returns:
            str: 渲染后的 HTML 内容
        """
        page = self._context.new_page()
        try:
            page.goto(url, wait_until="networkidle")
            return page.content()
        finally:
            page.close()
    
    def screenshot(self, url, path=None, full_page=False):
        """
        页面截图
        
        Args:
            url: 目标 URL
            path: 保存路径，如 "screenshot.png"
            full_page: 是否截取整个页面，默认 False
            
        Returns:
            bytes: 截图的二进制数据
        """
        page = self._context.new_page()
        try:
            page.goto(url, wait_until="networkidle")
            return page.screenshot(path=path, full_page=full_page)
        finally:
            page.close()
    
    def pdf(self, url, path=None):
        """
        生成页面 PDF
        
        Args:
            url: 目标 URL
            path: 保存路径，如 "page.pdf"
            
        Returns:
            bytes: PDF 的二进制数据
            
        Note:
            PDF 生成仅在无头模式下可用
        """
        if not self.headless:
            raise ValueError("PDF 生成仅在无头模式 (headless=True) 下可用")
        
        page = self._context.new_page()
        try:
            page.goto(url, wait_until="networkidle")
            return page.pdf(path=path)
        finally:
            page.close()
    
    def execute_script(self, url, script):
        """
        在页面中执行 JavaScript
        
        Args:
            url: 目标 URL
            script: 要执行的 JavaScript 代码
            
        Returns:
            执行结果
        """
        page = self._context.new_page()
        try:
            page.goto(url, wait_until="networkidle")
            return page.evaluate(script)
        finally:
            page.close()
    
    def new_page(self):
        """
        创建新页面
        
        Returns:
            Page: 新的 Playwright Page 对象
        """
        return self._context.new_page()
    
    def close(self):
        """关闭浏览器和代理服务器"""
        try:
            self._context.close()
        except:
            pass
        
        try:
            self._browser.close()
        except:
            pass
        
        try:
            self._playwright.stop()
        except:
            pass
        
        try:
            self._proxy_server.stop()
        except:
            pass
    
    def __enter__(self):
        """支持 with 语句"""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """支持 with 语句"""
        self.close()
        return False

