"""
窗口控制 Mixin
"""
from typing import Optional, TYPE_CHECKING

from loguru import logger

if TYPE_CHECKING:
    from ..tab import Tab
    from playwright.async_api import BrowserContext


class WindowMixin:
    """窗口控制功能"""

    # 这些属性由其他 mixin 或 core 定义
    _tabs: dict[str, "Tab"]
    _current_tab: Optional[str]
    _context: "BrowserContext"
    config: "Config"

    async def maximize(self, tab_id: Optional[str] = None) -> bool:
        """
        最大化浏览器窗口

        Args:
            tab_id: 标签页ID

        Returns:
            bool: 是否成功
        """
        tab = self.get_tab(tab_id)

        # 获取屏幕尺寸
        try:
            screen = await tab.page.evaluate("""
                () => ({
                    width: screen.availWidth || screen.width || 1920,
                    height: screen.availHeight || screen.height || 1080
                })
            """)
        except:
            screen = {"width": 1920, "height": 1080}

        # 方法1: 使用 CDP (仅 Chromium)
        if self.config.browser_type == "chromium":
            try:
                cdp = await self._context.new_cdp_session(tab.page)

                # 获取当前窗口ID
                result = await cdp.send("Browser.getWindowForTarget")
                window_id = result.get("windowId")

                if window_id:
                    # 先设置为正常状态，然后设置边界
                    await cdp.send("Browser.setWindowBounds", {
                        "windowId": window_id,
                        "bounds": {
                            "windowState": "normal",
                            "width": screen["width"],
                            "height": screen["height"]
                        }
                    })
                    # 再设置为最大化
                    await cdp.send("Browser.setWindowBounds", {
                        "windowId": window_id,
                        "bounds": {"windowState": "maximized"}
                    })

                    # 更新视口以匹配窗口
                    await tab.page.set_viewport_size({
                        "width": screen["width"],
                        "height": screen["height"]
                    })

                    logger.info(f"窗口已最大化 (CDP): {screen['width']}x{screen['height']}")
                    return True
            except Exception as e:
                logger.debug(f"CDP最大化失败: {e}")

        # 方法2: 设置视口为屏幕大小（通用方案）
        try:
            await tab.page.set_viewport_size({
                "width": screen["width"],
                "height": screen["height"]
            })
            logger.info(f"窗口已最大化 (视口): {screen['width']}x{screen['height']}")
            return True
        except Exception as e:
            logger.error(f"窗口最大化失败: {e}")
            return False

    async def set_viewport(
        self,
        width: int,
        height: int,
        tab_id: Optional[str] = None
    ):
        """
        设置视口大小

        Args:
            width: 宽度
            height: 高度
            tab_id: 标签页ID
        """
        tab = self.get_tab(tab_id)
        await tab.page.set_viewport_size({"width": width, "height": height})
        logger.info(f"视口已设置: {width}x{height}")

    async def get_viewport(self, tab_id: Optional[str] = None) -> dict:
        """
        获取当前视口大小

        Args:
            tab_id: 标签页ID

        Returns:
            dict: {"width": int, "height": int}
        """
        tab = self.get_tab(tab_id)

        # 优先获取实际窗口内部尺寸
        try:
            size = await tab.page.evaluate("""
                () => ({
                    width: window.innerWidth,
                    height: window.innerHeight
                })
            """)
            return size
        except:
            pass

        # 回退到 Playwright 视口
        viewport = tab.page.viewport_size
        return viewport or {}

    async def get_screen_size(self, tab_id: Optional[str] = None) -> dict:
        """
        获取屏幕尺寸

        Args:
            tab_id: 标签页ID

        Returns:
            dict: {"width": int, "height": int}
        """
        tab = self.get_tab(tab_id)

        try:
            screen = await tab.page.evaluate("""
                () => ({
                    width: screen.availWidth || screen.width,
                    height: screen.availHeight || screen.height
                })
            """)
            return screen
        except:
            return {"width": 1920, "height": 1080}
