"""Playwright 浏览器生命周期管理"""

from playwright.sync_api import sync_playwright, Browser, BrowserContext, Page, Playwright
from typing import Optional, Literal, Dict, Any
from pathlib import Path

from ..reference import GSTORE, INFO

BrowserType = Literal["chromium", "firefox", "webkit"]


class BrowserManager:
    """Playwright 浏览器生命周期管理器

    负责浏览器的启动、配置和关闭。
    支持 chromium、firefox、webkit 三种浏览器。
    支持 trace 录制和视频录制。
    """

    def __init__(self):
        self._playwright: Optional[Playwright] = None
        self._browser: Optional[Browser] = None
        self._context: Optional[BrowserContext] = None
        self._page: Optional[Page] = None
        self._trace_enabled: bool = False
        self._video_enabled: bool = False

    def launch(
        self,
        browser_type: BrowserType = "chromium",
        headless: bool = False,
        slow_mo: int = 0,
        trace: bool = False,
        video: bool = False,
        timeout: int = 30000,
        viewport: Optional[Dict[str, int]] = None,
        locale: str = "zh-CN",
        timezone_id: str = "Asia/Shanghai",
        **kwargs
    ) -> Page:
        """启动浏览器并返回页面

        Args:
            browser_type: 浏览器类型 (chromium, firefox, webkit)
            headless: 是否无头模式
            slow_mo: 操作延迟 (毫秒)
            trace: 是否开启 trace 录制
            video: 是否开启视频录制
            timeout: 默认超时时间 (毫秒)
            viewport: 视口大小 {"width": 1920, "height": 1080}
            locale: 语言区域
            timezone_id: 时区
            **kwargs: 其他 Playwright 启动参数

        Returns:
            Page: Playwright 页面实例
        """
        INFO(f"启动浏览器: {browser_type}, headless={headless}")

        self._playwright = sync_playwright().start()

        # 选择浏览器类型
        browser_launcher = getattr(self._playwright, browser_type)

        # 浏览器启动参数
        launch_options = {
            'headless': headless,
            'slow_mo': slow_mo,
        }
        launch_options.update(kwargs)

        self._browser = browser_launcher.launch(**launch_options)

        # 创建上下文参数
        context_options: Dict[str, Any] = {
            'locale': locale,
            'timezone_id': timezone_id,
        }

        if viewport:
            context_options['viewport'] = viewport
        else:
            context_options['viewport'] = {'width': 1920, 'height': 1080}

        # 视频录制配置
        if video:
            self._video_enabled = True
            video_dir = Path('result/video')
            video_dir.mkdir(parents=True, exist_ok=True)
            context_options['record_video_dir'] = str(video_dir)
            context_options['record_video_size'] = {'width': 1920, 'height': 1080}
            INFO("视频录制已启用")

        self._context = self._browser.new_context(**context_options)

        # 开启 trace 录制
        if trace:
            self._trace_enabled = True
            self._context.tracing.start(
                screenshots=True,
                snapshots=True,
                sources=True
            )
            INFO("Trace 录制已启用")

        # 创建页面
        self._page = self._context.new_page()

        # 设置默认超时
        self._page.set_default_timeout(timeout)
        self._page.set_default_navigation_timeout(timeout)

        # 更新全局存储
        GSTORE['browser'] = self._browser
        GSTORE['context'] = self._context
        GSTORE['page'] = self._page

        INFO("浏览器启动成功")
        return self._page

    def new_page(self) -> Page:
        """创建新页面

        Returns:
            Page: 新的页面实例
        """
        if not self._context:
            raise RuntimeError("浏览器上下文未初始化")

        page = self._context.new_page()
        return page

    def close(self, save_trace: Optional[str] = None) -> None:
        """关闭浏览器

        Args:
            save_trace: trace 文件保存路径 (如果开启了 trace)
        """
        INFO("关闭浏览器...")

        # 保存 trace
        if self._trace_enabled and self._context and save_trace:
            trace_path = Path(save_trace)
            trace_path.parent.mkdir(parents=True, exist_ok=True)
            self._context.tracing.stop(path=str(trace_path))
            INFO(f"Trace 已保存: {trace_path}")

        # 关闭上下文
        if self._context:
            self._context.close()
            self._context = None

        # 关闭浏览器
        if self._browser:
            self._browser.close()
            self._browser = None

        # 停止 Playwright
        if self._playwright:
            self._playwright.stop()
            self._playwright = None

        # 清理全局存储
        GSTORE['browser'] = None
        GSTORE['context'] = None
        GSTORE['page'] = None

        INFO("浏览器已关闭")

    @property
    def page(self) -> Optional[Page]:
        """当前页面实例"""
        return self._page

    @property
    def context(self) -> Optional[BrowserContext]:
        """浏览器上下文实例"""
        return self._context

    @property
    def browser(self) -> Optional[Browser]:
        """浏览器实例"""
        return self._browser

    @property
    def is_running(self) -> bool:
        """浏览器是否在运行"""
        return self._browser is not None and self._browser.is_connected()

    def __enter__(self) -> 'BrowserManager':
        """上下文管理器入口"""
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        """上下文管理器出口"""
        self.close()
