"""Utility functions for NotebookLM API client."""

import json
import urllib.parse
from datetime import UTC, datetime
from typing import Any

# RPC ID to method name mapping for debug logging
RPC_NAMES = {
    "wXbhsf": "list_notebooks",
    "rLM1Ne": "get_notebook",
    "CCqFvf": "create_notebook",
    "s0tc2d": "rename_notebook",
    "WWINqb": "delete_notebook",
    "izAoDd": "add_source",
    "hizoJc": "get_source",
    "yR9Yof": "check_freshness",
    "FLmJqe": "sync_drive",
    "tGMBJ": "delete_source",
    "b7Wfje": "rename_source",
    "hPTbtc": "get_conversations",
    "J7Gthc": "delete_chat_history",
    "hT54vc": "preferences",
    "ozz5Z": "add_source_v2",
    "ZwVcOc": "settings",
    "VfAZjd": "get_summary",
    "tr032e": "get_source_guide",
    "Ljjv0c": "start_fast_research",
    "QA9ei": "start_deep_research",
    "e3bVqc": "poll_research",
    "LBwxtb": "import_research",
    "R7cb6c": "create_studio",
    "gArtLc": "poll_studio",
    "V5N4be": "delete_studio",
    "v9rmvd": "get_interactive_html",
    "yyryJe": "generate_mind_map",
    "CYK0Xb": "save_mind_map",
    "cFji9": "list_mind_maps",
    "AH0mwd": "delete_mind_map",
    "QDyure": "share_notebook",
    "JFMDGd": "get_share_status",
    "KmcKPe": "revise_slide_deck",
    "agX4Bc": "label_manage",
    "le8sX": "label_mutate",
    "GyzE7e": "label_delete",
}


def _format_debug_json(data: Any, max_length: int = 2000) -> str:
    """Format data as pretty-printed JSON for debug logging."""
    try:
        formatted = json.dumps(data, indent=2, ensure_ascii=False)
        if len(formatted) > max_length:
            return formatted[:max_length] + "\n  ... (truncated)"
        return formatted
    except (TypeError, ValueError):
        result = str(data)
        if len(result) > max_length:
            return result[:max_length] + "... (truncated)"
        return result


def _decode_request_body(body: str) -> dict[str, Any]:
    """Decode URL-encoded request body and parse JSON structures."""
    result = {}
    try:
        parsed = urllib.parse.parse_qs(body.rstrip("&"))
        if "f.req" in parsed:
            f_req_raw = parsed["f.req"][0]
            try:
                f_req = json.loads(f_req_raw)
                result["f.req"] = f_req
                if isinstance(f_req, list) and len(f_req) > 0:
                    inner = f_req[0]
                    if isinstance(inner, list) and len(inner) > 0:
                        rpc_call = inner[0]
                        if isinstance(rpc_call, list) and len(rpc_call) >= 2:
                            result["rpc_id"] = rpc_call[0]
                            params_str = rpc_call[1]
                            if isinstance(params_str, str):
                                try:
                                    result["params"] = json.loads(params_str)
                                except json.JSONDecodeError:
                                    result["params"] = params_str
            except json.JSONDecodeError:
                result["f.req"] = f_req_raw
        if "at" in parsed:
            result["at"] = "(csrf_token)"
    except Exception:
        result["raw"] = body[:500] if len(body) > 500 else body
    return result


def _parse_url_params(url: str) -> dict[str, Any]:
    """Parse URL query parameters for debug display."""
    try:
        parsed = urllib.parse.urlparse(url)
        params = urllib.parse.parse_qs(parsed.query)
        return {k: v[0] if len(v) == 1 else v for k, v in params.items()}
    except Exception:
        return {}


def parse_timestamp(ts_array: list | None) -> str | None:
    """Convert [seconds, nanoseconds] timestamp array to ISO format string."""
    if not ts_array or not isinstance(ts_array, list) or len(ts_array) < 1:
        return None
    try:
        seconds = ts_array[0]
        if not isinstance(seconds, (int, float)):
            return None
        dt = datetime.fromtimestamp(seconds, tz=UTC)
        return dt.strftime("%Y-%m-%dT%H:%M:%SZ")
    except (ValueError, OSError, OverflowError):
        return None


def extract_cookies_from_chrome_export(cookie_data: str | list[dict]) -> dict[str, str]:
    """Extract cookies from Chrome export format (JSON) or header string."""
    if isinstance(cookie_data, list):
        return {c.get("name"): c.get("value") for c in cookie_data if "name" in c and "value" in c}
    if not isinstance(cookie_data, str):
        return {}
    try:
        data = json.loads(cookie_data)
        if isinstance(data, list):
            return {c.get("name"): c.get("value") for c in data if "name" in c and "value" in c}
        if isinstance(data, dict):
            return {str(k): str(v) for k, v in data.items()}
    except json.JSONDecodeError:
        pass
    cookies = {}
    for item in cookie_data.split(";"):
        if "=" in item:
            name, value = item.strip().split("=", 1)
            name = name.strip()
            if name:
                cookies[name] = value
    return cookies
