"""通用 App Page Object 基类。"""

from datetime import datetime
from pathlib import Path

from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

SCREENSHOTS_DIR = Path("output/screenshots")


class AppBasePage:
    """App Page Object 基类 — 各端通用。"""

    def __init__(self, driver, platform: str, timeout_ms: int = 30_000):
        self.driver = driver
        self.platform = platform  # "android" | "ios"
        self.timeout = timeout_ms / 1000

    def wait_visible_by_id(self, accessibility_id: str, timeout_s: float | None = None) -> None:
        wait = WebDriverWait(self.driver, timeout=timeout_s or self.timeout)
        wait.until(
            EC.visibility_of_element_located((AppiumBy.ACCESSIBILITY_ID, accessibility_id))
        )

    def wait_visible_by_text(self, text: str, timeout_s: float | None = None) -> None:
        wait = WebDriverWait(self.driver, timeout=timeout_s or self.timeout)
        locator = (
            (AppiumBy.XPATH, f"//*[@text='{text}']")
            if self.platform == "android"
            else (AppiumBy.XPATH, f"//*[@label='{text}']")
        )
        wait.until(EC.visibility_of_element_located(locator))

    def tap_by_id(self, accessibility_id: str) -> None:
        self.wait_visible_by_id(accessibility_id)
        self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, accessibility_id).click()

    def tap_by_text(self, text: str) -> None:
        strategy = AppiumBy.XPATH
        locator = (
            f"//*[@text='{text}']"
            if self.platform == "android"
            else f"//*[@label='{text}']"
        )
        wait = WebDriverWait(self.driver, timeout=self.timeout)
        wait.until(EC.visibility_of_element_located((strategy, locator)))
        self.driver.find_element(strategy, locator).click()

    def fill_by_id(self, accessibility_id: str, value: str) -> None:
        self.wait_visible_by_id(accessibility_id)
        element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, accessibility_id)
        element.clear()
        element.send_keys(value)

    def scroll_down(self) -> None:
        size = self.driver.get_window_size()
        self.driver.swipe(
            start_x=size["width"] // 2,
            start_y=int(size["height"] * 0.7),
            end_x=size["width"] // 2,
            end_y=int(size["height"] * 0.3),
            duration=500,
        )

    def screenshot(self, name: str) -> 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}_{self.platform}_{ts}.png")
        self.driver.save_screenshot(path)
        return path
