import requests
from .chat import Chat
from .images import Images
from .embeddings import Embeddings
from .audio import Audio
from .errors import BeaverError


class Beaver:
    def __init__(self, api_key: str, base_url: str = "https://api.beaverai.cloud/v1"):
        if not api_key:
            raise ValueError("api_key is required")

        self.api_key = api_key
        self.base_url = base_url.rstrip("/")
        
        # Initialize sub-clients
        self.chat = Chat(self)
        self.images = Images(self)
        self.embeddings = Embeddings(self)
        self.audio = Audio(self)

    def _post(self, path: str, payload: dict) -> dict:
        """Shared logic for JSON POST requests."""
        response = requests.post(
            f"{self.base_url}{path}",
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.api_key}",
            },
            json=payload,
        )

        if not response.ok:
            self._handle_error(response)

        return response.json()

    def _post_raw(self, path: str, payload: dict) -> bytes:
        """Shared logic for POST requests that return raw bytes (Audio)."""
        response = requests.post(
            f"{self.base_url}{path}",
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.api_key}",
            },
            json=payload,
        )

        if not response.ok:
            self._handle_error(response)

        return response.content

    def _handle_error(self, response: requests.Response):
        """Unified error handling."""
        try:
            error_data = response.json()
            error_code = error_data.get("error", {}).get("type")
            error_message = error_data.get("error", {}).get("message", f"HTTP {response.status_code}")
        except Exception:
            error_code = None
            error_message = f"HTTP {response.status_code}"

        raise BeaverError(error_message, response.status_code, error_code)
