"""Tracing OAuth client — records all Magento API requests and responses for debugging."""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from magento.oauth_client import MagentoOAuthClient


def _sanitize_for_trace(obj: Any, max_len: int = 2000) -> Any:
    """Truncate large payloads for trace output."""
    if obj is None:
        return None
    if isinstance(obj, dict):
        return {k: _sanitize_for_trace(v, max_len) for k, v in obj.items()}
    if isinstance(obj, list):
        return [_sanitize_for_trace(x, max_len) for x in obj[:50]]  # cap list length
    if isinstance(obj, str) and len(obj) > max_len:
        return obj[:max_len] + "...[truncated]"
    return obj


class TracingOAuthClient(MagentoOAuthClient):
    """
    OAuth client that delegates to parent but records each request/response.
    Use api_trace list (mutated in place) to capture calls.
    """

    def __init__(self, api_trace: List[Dict[str, Any]], **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self._trace = api_trace

    def _request(
        self,
        method: str,
        path: str,
        *,
        json: Optional[Dict[str, Any]] = None,
        params: Optional[Dict[str, str]] = None,
    ) -> tuple[int, Optional[Dict[str, Any]], Optional[str]]:
        url = self._url(path)
        status, body, err = super()._request(method, path, json=json, params=params)
        entry: Dict[str, Any] = {
            "method": method,
            "path": path,
            "url": url,
            "params": dict(params) if params else None,
            "request_body": _sanitize_for_trace(json),
            "status": status,
            "response_body": _sanitize_for_trace(body),
            "error": err,
        }
        self._trace.append(entry)
        return status, body, err

    def _request_url(
        self, method: str, full_url: str, **kwargs: Any
    ) -> tuple[int, Optional[Dict[str, Any]], Optional[str]]:
        status, body, err = super()._request_url(method, full_url, **kwargs)
        json_body = kwargs.get("json")
        self._trace.append({
            "method": method,
            "path": "(full_url)",
            "url": full_url[:500],
            "params": None,
            "request_body": _sanitize_for_trace(json_body),
            "status": status,
            "response_body": _sanitize_for_trace(body),
            "error": err,
        })
        return status, body, err
