"""Argparse helpers shared by ``screenshot.py`` and ``record.py``."""
from __future__ import annotations

import argparse
import json
import os
import tempfile
from pathlib import Path


def add_common_args(ap: argparse.ArgumentParser) -> None:
    """Add the args common to both screenshot and record entry points."""
    ap.add_argument(
        "-b", "--browser", choices=["chromium", "firefox", "webkit"],
        default="chromium", help="浏览器内核（默认 chromium）",
    )
    ap.add_argument("--device", help='设备模拟名，如 "iPhone 15 Pro"、"Pixel 7"')
    ap.add_argument(
        "--viewport",
        help='viewport "宽,高"，如 "1280,800"；与 --device 互斥时以 --device 为准',
    )
    ap.add_argument("--wait-for-selector", help="动作前等待该 CSS 选择器出现")
    ap.add_argument("--wait-for-timeout", type=int, help="动作前固定等待毫秒数")
    ap.add_argument(
        "--color-scheme", choices=["light", "dark", "no-preference"],
        help="模拟 prefers-color-scheme",
    )
    ap.add_argument("--user-agent", help="覆盖 User-Agent")
    ap.add_argument(
        "--timeout", type=int, help="Playwright 全局动作超时（ms，默认无超时）",
    )
    ap.add_argument(
        "--ignore-https-errors", action="store_true", help="忽略 HTTPS 证书错误",
    )
    ap.add_argument("--storage-state", help="storageState JSON 文件路径")
    ap.add_argument(
        "--cookies",
        help='Playwright cookies JSON 字符串或 JSON 文件路径（顶层为数组）',
    )


def parse_cookies(raw: str) -> list[dict]:
    p = Path(raw)
    if p.exists() and p.is_file():
        try:
            data = json.loads(p.read_text())
        except json.JSONDecodeError as e:
            raise SystemExit(f"--cookies 文件不是合法 JSON：{e}")
    else:
        try:
            data = json.loads(raw)
        except json.JSONDecodeError:
            raise SystemExit(
                "--cookies 需为 JSON 字符串或 JSON 文件路径，顶层为 cookie 数组。"
            )
    if not isinstance(data, list):
        raise SystemExit("--cookies 顶层应为数组（Playwright cookies 格式）。")
    return data


def build_storage(args) -> tuple[str | None, bool]:
    """Returns (storage_state_path, is_temp). Caller must unlink if is_temp."""
    if getattr(args, "storage_state", None):
        return args.storage_state, False
    if getattr(args, "cookies", None):
        cookies = parse_cookies(args.cookies)
        fd, path = tempfile.mkstemp(prefix="pw_storage_", suffix=".json")
        with os.fdopen(fd, "w") as f:
            json.dump({"cookies": cookies, "origins": []}, f)
        return path, True
    return None, False


def parse_viewport(raw: str) -> list[int]:
    parts = [s.strip() for s in raw.split(",")]
    if len(parts) != 2:
        raise SystemExit('--viewport 需为 "宽,高"')
    try:
        return [int(p) for p in parts]
    except ValueError:
        raise SystemExit("--viewport 必须是整数")


def parse_clip(raw: str) -> list[float]:
    parts = [s.strip() for s in raw.split(",")]
    if len(parts) != 4:
        raise SystemExit('--clip 需为 "x,y,w,h" 四个数字')
    try:
        return [float(p) for p in parts]
    except ValueError:
        raise SystemExit("--clip 的四个值必须是数字")


def common_args_to_cfg(args, cfg: dict) -> None:
    """Merge the common-args values into a cfg dict (shared by entry points)."""
    if args.device:
        cfg["device"] = args.device
    if args.viewport:
        cfg["viewport"] = parse_viewport(args.viewport)
    if args.color_scheme:
        cfg["colorScheme"] = args.color_scheme
    if args.user_agent:
        cfg["userAgent"] = args.user_agent
    if args.timeout is not None:
        cfg["timeout"] = args.timeout
    if args.ignore_https_errors:
        cfg["ignoreHttpsErrors"] = True
    if args.wait_for_selector:
        cfg["waitForSelector"] = args.wait_for_selector
    if args.wait_for_timeout is not None:
        cfg["waitForTimeout"] = args.wait_for_timeout
