from __future__ import annotations

import json
from typing import Any, Mapping, Optional
from urllib.error import HTTPError
from urllib.request import Request, urlopen

from .headers import _tracking_headers


def _request_raw(
    url: str,
    *,
    payload: Optional[Any] = None,
    method: str = "POST",
    headers: Optional[Mapping[str, str]] = None,
    timeout: float = 30.0,
) -> dict[str, Any]:
    """Execute raw HTTP request and return status/headers/body."""
    outbound_headers = _tracking_headers(headers)
    data: Optional[bytes] = None

    if payload is not None:
        data = json.dumps(payload).encode("utf-8")
        if "Content-Type" not in outbound_headers:
            outbound_headers["Content-Type"] = "application/json"

    req = Request(url=url, data=data, headers=outbound_headers, method=method.upper())

    try:
        with urlopen(req, timeout=timeout) as response:
            body = response.read()
            return {
                "ok": True,
                "status": getattr(response, "status", 200),
                "headers": response.headers,
                "body": body,
            }
    except HTTPError as e:
        body = b""
        try:
            body = e.read()
        except Exception:
            body = b""
        return {
            "ok": False,
            "status": e.code,
            "headers": e.headers,
            "body": body,
        }
