"""Async HTTP client for PDF generation via the ComplyForm API.

Sends rendered HTML to ``/v1/report/pdf`` and returns raw PDF bytes.
Uses httpx.AsyncClient with Bearer auth.
"""

from __future__ import annotations

import sys

import httpx

from complyform.core.errors import (
    GotenbergPayloadTooLargeError,
    GotenbergRenderError,
    GotenbergTimeoutError,
)

API_TIMEOUT = 90.0
_MAX_HTML_BYTES = 10 * 1024 * 1024  # 10 MB


async def request_pdf(
    api_base_url: str,
    api_key: str,
    html_content: str,
    brand: dict[str, object] | None = None,
    logo_base64: str | None = None,
) -> bytes:
    """Request PDF rendering from the ComplyForm API.

    Parameters
    ----------
    api_base_url:
        Base URL of the ComplyForm API (no trailing slash).
    api_key:
        Bearer token for authentication.
    html_content:
        Rendered HTML string to convert to PDF.
    brand:
        Optional brand config dict (company_name, colors, etc.).
    logo_base64:
        Optional base64-encoded logo image.

    Returns
    -------
    bytes
        Raw PDF content.

    Raises
    ------
    GotenbergPayloadTooLargeError
        If HTML exceeds 10 MB.
    GotenbergTimeoutError
        If the API request times out.
    GotenbergRenderError
        If the API returns a 4xx/5xx error.
    """
    html_bytes = html_content.encode("utf-8")
    size = len(html_bytes)

    if size > _MAX_HTML_BYTES:
        raise GotenbergPayloadTooLargeError(size)

    url = f"{api_base_url.rstrip('/')}/v1/report/pdf"

    payload: dict[str, object] = {"html": html_content}
    if brand is not None:
        payload["brand"] = brand
    if logo_base64 is not None:
        payload["logo_base64"] = logo_base64

    print(f"Requesting PDF from {url}", file=sys.stderr)

    async with httpx.AsyncClient(timeout=API_TIMEOUT) as client:
        try:
            response = await client.post(
                url,
                json=payload,
                headers={"Authorization": f"Bearer {api_key}"},
            )
        except httpx.TimeoutException as exc:
            raise GotenbergTimeoutError() from exc

        if response.status_code == 413:
            raise GotenbergPayloadTooLargeError(size)

        if response.status_code >= 400:
            detail = response.text[:500] if response.text else "No details"
            raise GotenbergRenderError(response.status_code, detail)

    return response.content
