"""Page Object 基类 — 封装所有页面共享的通用操作。

每个具体页面应继承 BasePage，在 __init__ 中声明所有定位器。

Usage:
    class LoginPage(BasePage):
        def __init__(self, page):
            super().__init__(page)
            self.phone_input = page.get_by_placeholder("请输入用户名")
            self.login_btn = page.get_by_role("button", name="登录")
"""

from datetime import datetime
from pathlib import Path
from typing import Optional

from playwright.sync_api import Page, Locator, expect

SCREENSHOTS_DIR = Path("output/screenshots")


class BasePage:
    """Page Object 基类。"""

    def __init__(self, page: Page, timeout_ms: int = 30_000):
        self.page = page
        self.timeout = timeout_ms

    # ── 通用等待 ──

    def wait_visible(self, locator: Locator, timeout_ms: Optional[int] = None) -> None:
        """等待元素可见。"""
        expect(locator).to_be_visible(timeout=timeout_ms or self.timeout)

    def wait_hidden(self, locator: Locator, timeout_ms: Optional[int] = None) -> None:
        """等待元素消失（如 Loading 遮罩）。"""
        expect(locator).to_be_hidden(timeout=timeout_ms or self.timeout)

    def wait_for_text(self, text: str, timeout_ms: Optional[int] = None) -> None:
        """等待页面上出现指定文本。"""
        expect(self.page.get_by_text(text)).to_be_visible(timeout=timeout_ms or self.timeout)

    # ── 通用操作 ──

    def fill_field(self, locator: Locator, value: str) -> None:
        """安全填写输入框（先等待可见，再清空后填写）。"""
        self.wait_visible(locator)
        locator.clear()
        locator.fill(value)

    def click_when_ready(self, locator: Locator) -> None:
        """安全点击（等待可见 + 可操作）。"""
        self.wait_visible(locator)
        locator.click()

    def get_text(self, locator: Locator) -> str:
        """获取元素的 inner text。"""
        self.wait_visible(locator)
        return locator.inner_text()

    # ── 截图 ──

    def screenshot(self, name: str, full_page: bool = False) -> str:
        """关键节点截图，返回文件路径。"""
        scenario_dir = SCREENSHOTS_DIR / self.__class__.__name__
        scenario_dir.mkdir(parents=True, exist_ok=True)
        ts = datetime.now().strftime("%Y%m%d_%H%M%S")
        path = str(scenario_dir / f"{name}_{ts}.png")
        self.page.screenshot(path=path, full_page=full_page)
        return path

    # ── 导航 ──

    def navigate(self, url: str) -> None:
        """导航到指定 URL 并等待页面加载完成。"""
        self.page.goto(url, wait_until="domcontentloaded")
