"""
BIBIVIDI — SDK Integration Helpers

Drop-in httpx transports that route Anthropic / OpenAI SDK requests through
the BIBIVIDI proxy without any changes to application code.

Usage (Anthropic):
    import anthropic
    from bvd.sdk import anthropic_http_client

    client = anthropic.Anthropic(
        api_key="sk-ant-...",
        http_client=anthropic_http_client(),
    )
    # All requests now flow through http://127.0.0.1:8080

Usage (Anthropic async):
    client = anthropic.AsyncAnthropic(
        api_key="sk-ant-...",
        http_client=async_anthropic_http_client(),
    )

Usage (OpenAI):
    import openai
    from bvd.sdk import openai_http_client

    client = openai.OpenAI(
        api_key="sk-...",
        http_client=openai_http_client(),
    )
"""
from __future__ import annotations

import httpx

from bvd.config import settings

# ── Internal transport implementation ─────────────────────────────────────────

def _rewrite_url(url: httpx.URL) -> httpx.URL:
    """Redirect the request to the local BIBIVIDI proxy, keeping the original path/query."""
    return url.copy_with(
        scheme="http",
        host=settings.proxy_host,
        port=settings.proxy_port,
    )


def _override_host(raw_headers: list[tuple[bytes, bytes]], host: str) -> list[tuple[bytes, bytes]]:
    """Return a new header list with the Host set to ``host``."""
    return [
        (k, v) for k, v in raw_headers if k.lower() != b"host"
    ] + [(b"host", host.encode())]


class BIBIVIDITransport(httpx.BaseTransport):
    """
    Sync httpx transport for use with ``anthropic.Anthropic`` / ``openai.OpenAI``.

    Transparently rewrites every request so it is sent to the BIBIVIDI proxy
    (http://127.0.0.1:8080) while preserving the original ``Host`` header so
    the proxy can identify the target AI API.
    """

    def __init__(self) -> None:
        self._inner = httpx.HTTPTransport()

    def handle_request(self, request: httpx.Request) -> httpx.Response:
        target_host = request.url.host
        body = request.read()
        new_request = httpx.Request(
            method=request.method,
            url=_rewrite_url(request.url),
            headers=_override_host(list(request.headers.raw), target_host),
            content=body,
            extensions=request.extensions,
        )
        return self._inner.handle_request(new_request)

    def close(self) -> None:
        self._inner.close()


class AsyncBIBIVIDITransport(httpx.AsyncBaseTransport):
    """
    Async httpx transport for use with ``anthropic.AsyncAnthropic`` / ``openai.AsyncOpenAI``.
    """

    def __init__(self) -> None:
        self._inner = httpx.AsyncHTTPTransport()

    async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
        target_host = request.url.host
        body = await request.aread()
        new_request = httpx.Request(
            method=request.method,
            url=_rewrite_url(request.url),
            headers=_override_host(list(request.headers.raw), target_host),
            content=body,
            extensions=request.extensions,
        )
        return await self._inner.handle_async_request(new_request)

    async def aclose(self) -> None:
        await self._inner.aclose()


# ── Public helpers ─────────────────────────────────────────────────────────────

def anthropic_http_client(**kwargs: object) -> httpx.Client:
    """Return a sync httpx.Client configured to route through BIBIVIDI."""
    return httpx.Client(transport=BIBIVIDITransport(), **kwargs)  # type: ignore[arg-type]


def async_anthropic_http_client(**kwargs: object) -> httpx.AsyncClient:
    """Return an async httpx.AsyncClient configured to route through BIBIVIDI."""
    return httpx.AsyncClient(transport=AsyncBIBIVIDITransport(), **kwargs)  # type: ignore[arg-type]


# OpenAI uses the same httpx interface
openai_http_client = anthropic_http_client
async_openai_http_client = async_anthropic_http_client
