"""
LuxurAI SDK — http.py
Base HTTP client. Uses only stdlib urllib — zero dependencies.
Optional: if httpx or requests is installed, uses them for async support.
"""

from __future__ import annotations
import json
import urllib.request
import urllib.error
from typing import Any, Dict, Optional

from .exceptions import (
    LuxurAIError,
    AuthenticationError,
    InsufficientBalanceError,
    ModelTrainingError,
    RateLimitError,
)


class HttpClient:
    """
    Minimal HTTP client — zero required dependencies.
    Uses stdlib urllib internally.
    """

    def __init__(self, api_key: str, base_url: str, timeout: int):
        self.api_key  = api_key
        self.base_url = base_url.rstrip("/")
        self.timeout  = timeout

    def _headers(self) -> Dict[str, str]:
        return {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type":  "application/json",
            "User-Agent":    "luxurai-python/0.1.0",
        }

    def _handle_error(self, status: int, body: dict) -> None:
        detail = body.get("detail", {})
        msg    = detail.get("message", str(detail)) if isinstance(detail, dict) else str(detail)

        if status == 401 or status == 403:
            raise AuthenticationError(
                f"Invalid API key. Get yours at luxurai.in → Dashboard → API Keys",
                status_code=status,
            )
        if status == 402:
            raise InsufficientBalanceError()
        if status == 429:
            raise RateLimitError("Too many requests. Please slow down.", status_code=429)
        if status == 503:
            coming_soon = detail.get("coming_soon", False) if isinstance(detail, dict) else False
            if coming_soon:
                raise ModelTrainingError(
                    "brainAI model is still training — generation coming soon! "
                    "Follow @luxurai_in for updates.",
                    status_code=503,
                )
        raise LuxurAIError(msg or f"HTTP {status}", status_code=status)

    def get(self, path: str) -> dict:
        url = f"{self.base_url}{path}"
        req = urllib.request.Request(url, headers=self._headers(), method="GET")
        try:
            with urllib.request.urlopen(req, timeout=self.timeout) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            body = {}
            try:
                body = json.loads(e.read().decode())
            except Exception:
                pass
            self._handle_error(e.code, body)

    def post(self, path: str, data: Optional[Dict[str, Any]] = None) -> dict:
        url     = f"{self.base_url}{path}"
        payload = json.dumps(data or {}).encode()
        req     = urllib.request.Request(url, data=payload, headers=self._headers(), method="POST")
        try:
            with urllib.request.urlopen(req, timeout=self.timeout) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            body = {}
            try:
                body = json.loads(e.read().decode())
            except Exception:
                pass
            self._handle_error(e.code, body)

    def delete(self, path: str) -> dict:
        url = f"{self.base_url}{path}"
        req = urllib.request.Request(url, headers=self._headers(), method="DELETE")
        try:
            with urllib.request.urlopen(req, timeout=self.timeout) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            body = {}
            try:
                body = json.loads(e.read().decode())
            except Exception:
                pass
            self._handle_error(e.code, body)
