from __future__ import annotations

import subprocess
import sys
from typing import Callable

from niannian.storage.feimao_auth import looks_like_feimao_session
from niannian.storage.quark_live import looks_like_quark_cookie

BrowserLoader = Callable[..., object]

_BROWSER_LOADERS: dict[str, str] = {
    "chrome": "chrome",
    "edge": "edge",
    "brave": "brave",
    "chromium": "chromium",
    "firefox": "firefox",
    "safari": "safari",
}


def read_clipboard() -> str:
    if sys.platform == "darwin":
        return subprocess.check_output(["pbpaste"], text=True).strip()
    if sys.platform == "win32":
        return subprocess.check_output(
            ["powershell", "-NoProfile", "-Command", "Get-Clipboard"],
            text=True,
        ).strip()
    raise RuntimeError("剪贴板自动读取仅支持 macOS / Windows，请用 --paste 从 stdin 粘贴")


def extract_quark_cookie_from_browser(browser: str = "chrome") -> str:
    """从本机浏览器 Cookie 库读取 quark.cn 会话（需 browser-cookie3）。"""
    loader_name = _BROWSER_LOADERS.get(browser.lower())
    if not loader_name:
        supported = ", ".join(sorted(_BROWSER_LOADERS))
        raise ValueError(f"不支持的浏览器 {browser!r}，可选: {supported}")

    try:
        import browser_cookie3
    except ImportError as exc:
        raise RuntimeError(
            "未安装 browser-cookie3。执行: pip install browser-cookie3\n"
            "或改用: niannian cloud login quark --clipboard / --paste"
        ) from exc

    loader: BrowserLoader = getattr(browser_cookie3, loader_name)

    pairs: dict[str, str] = {}
    try:
        jar = loader(domain_name="quark.cn")
    except Exception as exc:
        raise RuntimeError(
            f"读取 {browser} Cookie 失败: {exc}\n"
            "请确认已在浏览器登录 pan.quark.cn，并关闭浏览器后重试"
        ) from exc

    for cookie in jar:
        domain = str(getattr(cookie, "domain", "") or "")
        if "quark" not in domain:
            continue
        name = str(getattr(cookie, "name", "") or "")
        value = str(getattr(cookie, "value", "") or "")
        if name:
            pairs[name] = value

    if not pairs:
        raise RuntimeError(
            f"{browser} 中未找到 quark.cn Cookie。\n"
            "请先在浏览器打开 https://pan.quark.cn 并登录，然后重试。"
        )

    cookie_header = "; ".join(f"{name}={value}" for name, value in pairs.items())
    if not looks_like_quark_cookie(cookie_header):
        raise RuntimeError(
            "浏览器 Cookie 缺少夸克会话字段（__pus 等）。"
            "请确认 pan.quark.cn 已登录。"
        )
    return cookie_header


def extract_feimao_session_from_browser(browser: str = "chrome") -> str:
    """从本机浏览器 Cookie 库读取 feemoo.com 会话（需 browser-cookie3）。"""
    loader_name = _BROWSER_LOADERS.get(browser.lower())
    if not loader_name:
        supported = ", ".join(sorted(_BROWSER_LOADERS))
        raise ValueError(f"不支持的浏览器 {browser!r}，可选: {supported}")

    try:
        import browser_cookie3
    except ImportError as exc:
        raise RuntimeError(
            "未安装 browser-cookie3。执行: pip install browser-cookie3\n"
            "或改用: niannian cloud login feimao --clipboard / --paste"
        ) from exc

    loader: BrowserLoader = getattr(browser_cookie3, loader_name)
    pairs: dict[str, str] = {}
    for domain in ("feemoo.com", "www.feemoo.com"):
        try:
            jar = loader(domain_name=domain)
        except Exception:
            continue
        for cookie in jar:
            domain_name = str(getattr(cookie, "domain", "") or "")
            if "feemoo" not in domain_name:
                continue
            name = str(getattr(cookie, "name", "") or "")
            value = str(getattr(cookie, "value", "") or "")
            if name:
                pairs[name] = value

    if not pairs:
        raise RuntimeError(
            f"{browser} 中未找到 feemoo.com Cookie。\n"
            "请先在浏览器打开 https://www.feemoo.com 并登录，然后重试。"
        )

    session = "; ".join(f"{name}={value}" for name, value in pairs.items())
    if not looks_like_feimao_session(session):
        raise RuntimeError("浏览器 Cookie 缺少飞猫会话字段（feemootoken 等）。")
    return session


def audit_feimao_session(session: str) -> dict[str, bool | int]:
    lowered = session.lower()
    names = ["feemootoken", "feemoo_hw_token"]
    present = {
        name: f"{name}=" in lowered for name in names
    }
    present["cookie_string"] = session.count(";") >= 2
    return {"len": len(session), **present}


def audit_quark_cookie(cookie: str) -> dict[str, bool | int]:
    names = ["__pus", "__puus", "__uid", "ctoken", "__kps", "__kp", "__ktd", "_qk_bx_ck_v1"]
    present = {
        name: any(part.strip().startswith(f"{name}=") for part in cookie.split(";"))
        for name in names
    }
    return {"len": len(cookie), **present}
