"""
``httpx`` library integration.

Monkey-patches ``httpx.Client.send`` to capture outgoing HTTP requests.
"""

import time
import traceback

from overcast_sdk.integrations import Integration, DidNotEnable
from overcast_sdk.utils import capture_internal, _originals


class HttpxIntegration(Integration):
    identifier = "httpx"

    @staticmethod
    def setup_once():
        try:
            import httpx
        except ImportError:
            raise DidNotEnable("httpx is not installed")

        _originals["httpx_send"] = httpx.Client.send

        def _patched_send(self, request, **kwargs):
            from overcast_sdk.client import get_client
            from overcast_sdk.scope import get_current_scope

            url = str(request.url)
            method = request.method

            client = get_client()

            # Skip Overcast's own calls
            if client and client.options.get("base_url", "") in url:
                return _originals["httpx_send"](self, request, **kwargs)

            start = time.monotonic()
            try:
                response = _originals["httpx_send"](self, request, **kwargs)
                duration = time.monotonic() - start

                with capture_internal:
                    scope = get_current_scope()
                    scope.add_breadcrumb({
                        "type": "http",
                        "category": "httpx",
                        "message": f"{method} {url}",
                        "data": {
                            "url": url,
                            "method": method,
                            "status_code": response.status_code,
                            "duration_ms": round(duration * 1000),
                        },
                        "level": "error" if response.status_code >= 500 else "info",
                    })

                    if client:
                        meta = {
                            "type": "http_outgoing",
                            "library": "httpx",
                            "method": method,
                            "url": url,
                            "status_code": response.status_code,
                            "duration_s": round(duration, 3),
                        }
                        if response.status_code >= 400:
                            level = "ERROR" if response.status_code >= 500 else "WARNING"
                            client.enqueue(
                                level,
                                f"HTTP {response.status_code}: {method} {url}",
                                meta,
                            )

                return response

            except Exception as exc:
                duration = time.monotonic() - start
                with capture_internal:
                    if client:
                        client.enqueue("ERROR", f"httpx error: {method} {url} — {exc}", {
                            "type": "http_network_error",
                            "library": "httpx",
                            "method": method,
                            "url": url,
                            "duration_s": round(duration, 3),
                            "error": {
                                "type": type(exc).__name__,
                                "message": str(exc),
                            },
                        })
                raise

        httpx.Client.send = _patched_send
