"""Browser context / locator / wait helpers."""
from __future__ import annotations

from typing import Any

from . import js_loader
from .bootstrap import ensure_chromium


def pick_browser_type(p, name: str | None):
    if name == "firefox":
        return p.firefox
    if name == "webkit":
        return p.webkit
    return p.chromium


def build_context_options(p, cfg: dict, record_video_dir: str | None) -> dict:
    opts: dict[str, Any] = {}
    if cfg.get("device"):
        d = p.devices.get(cfg["device"])
        if not d:
            raise SystemExit(f"unknown device: {cfg['device']}")
        opts.update(d)
    elif isinstance(cfg.get("viewport"), (list, tuple)) and len(cfg["viewport"]) == 2:
        opts["viewport"] = {
            "width": int(cfg["viewport"][0]),
            "height": int(cfg["viewport"][1]),
        }
    if cfg.get("colorScheme"):
        opts["color_scheme"] = cfg["colorScheme"]
    if cfg.get("userAgent"):
        opts["user_agent"] = cfg["userAgent"]
    if cfg.get("ignoreHttpsErrors"):
        opts["ignore_https_errors"] = True
    if cfg.get("storageState"):
        opts["storage_state"] = cfg["storageState"]
    if record_video_dir:
        opts["record_video_dir"] = record_video_dir
        if opts.get("viewport"):
            opts["record_video_size"] = opts["viewport"]
    return opts


def launch_with_browser_install(p, browser_name: str | None, launch_kwargs: dict | None = None):
    btype = pick_browser_type(p, browser_name)
    try:
        return btype.launch(**(launch_kwargs or {}))
    except Exception as e:
        msg = str(e)
        if "Executable doesn't exist" in msg or "playwright install" in msg.lower():
            ensure_chromium()
            return btype.launch(**(launch_kwargs or {}))
        raise


def apply_pre_action_waits(page, cfg: dict) -> None:
    if cfg.get("waitForSelector"):
        page.wait_for_selector(cfg["waitForSelector"], timeout=cfg.get("timeout", 0))
    if isinstance(cfg.get("waitForTimeout"), (int, float)):
        page.wait_for_timeout(cfg["waitForTimeout"])


def wait_until_settled(page, cfg: dict) -> None:
    try:
        page.wait_for_load_state("networkidle", timeout=20000)
    except Exception:
        pass
    try:
        page.wait_for_function(js_loader.load("settled_check"), timeout=15000)
    except Exception:
        pass
    for sel in cfg.get("waitForReadySelectors") or []:
        try:
            page.wait_for_selector(sel, state="visible", timeout=10000)
        except Exception:
            pass
    page.wait_for_timeout(cfg.get("settleMs", 800))


def resolve_locator(page, selector: str):
    locator = page.locator(selector).first
    locator.wait_for(state="visible", timeout=15000)
    locator.scroll_into_view_if_needed()
    page.wait_for_timeout(250)
    return locator
