"""Maniac API client."""

from __future__ import annotations

from typing import Any

import httpx

from ._base import SyncAPIClient, AsyncAPIClient, DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES
from ._resources import (
    SyncChatResource,
    SyncContainersResource,
    SyncFilesResource,
    SyncModelsResource,
    SyncEvaluatorsResource,
    SyncEvaluationResource,
    SyncDatasetsResource,
    AsyncChatResource,
    AsyncContainersResource,
    AsyncFilesResource,
    AsyncModelsResource,
    AsyncEvaluatorsResource,
    AsyncEvaluationResource,
    AsyncDatasetsResource,
    AsyncOptimizationResource,
    SyncOptimizationResource,
)


class Maniac:
    """Synchronous Maniac API client.

    Usage:
        client = Maniac(api_key="your-api-key")

        # Chat completions (OpenAI-compatible)
        response = client.chat.completions.create(
            model="openai/gpt-4o",
            messages=[{"role": "user", "content": "Hello!"}]
        )

        # Streaming
        for chunk in client.chat.completions.create(
            model="openai/gpt-4o",
            messages=[{"role": "user", "content": "Hello!"}],
            stream=True
        ):
            print(chunk)

        # Containers
        container = client.containers.create(
            label="my-container",
            initial_model="openai/gpt-4o"
        )

        # Files
        file = client.files.create(file="data.jsonl", purpose="fine-tune")

        # Models
        models = client.models.list()

        # Evaluators
        evaluator = client.evaluators.create(
            type="judge",
            model="openai/gpt-4o",
            prompt="Rate the quality..."
        )

        # Evaluation runs
        run = client.evaluation.runs.create(
            container="my-container",
            evaluators=["evaluator-id"],
            models=["openai/gpt-4o"]
        )

        # Datasets
        dataset = client.datasets.create(
            name="my-dataset",
            container="my-container",
            size=100
        )
    """

    chat: SyncChatResource
    containers: SyncContainersResource
    files: SyncFilesResource
    models: SyncModelsResource
    evaluators: SyncEvaluatorsResource
    evaluation: SyncEvaluationResource
    datasets: SyncDatasetsResource
    optimization: SyncOptimizationResource

    def __init__(
        self,
        api_key: str | None = None,
        *,
        base_url: str | None = None,
        timeout: float = DEFAULT_TIMEOUT,
        max_retries: int = DEFAULT_MAX_RETRIES,
        http_client: httpx.Client | None = None,
    ) -> None:
        """Initialize the Maniac client.

        Args:
            api_key: API key. Falls back to MANIAC_API_KEY environment variable.
            base_url: Base URL. Falls back to MANIAC_BASE_URL or https://platform.maniac.ai.
            timeout: Request timeout in seconds.
            max_retries: Maximum number of retries for failed requests.
            http_client: Custom httpx.Client instance.
        """
        self._client = SyncAPIClient(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout,
            max_retries=max_retries,
            http_client=http_client,
        )

        # Initialize resources
        self.chat = SyncChatResource(self._client)
        self.containers = SyncContainersResource(self._client)
        self.files = SyncFilesResource(self._client)
        self.models = SyncModelsResource(self._client)
        self.evaluators = SyncEvaluatorsResource(self._client)
        self.evaluation = SyncEvaluationResource(self._client)
        self.datasets = SyncDatasetsResource(self._client)
        self.optimization = SyncOptimizationResource(self._client)

    def close(self) -> None:
        """Close the HTTP client."""
        self._client.close()

    def __enter__(self) -> Maniac:
        return self

    def __exit__(self, *args: Any) -> None:
        self.close()


class AsyncManiac:
    """Asynchronous Maniac API client.

    Usage:
        async with AsyncManiac(api_key="your-api-key") as client:
            response = await client.chat.completions.create(
                model="openai/gpt-4o",
                messages=[{"role": "user", "content": "Hello!"}]
            )

            # Streaming
            async for chunk in await client.chat.completions.create(
                model="openai/gpt-4o",
                messages=[{"role": "user", "content": "Hello!"}],
                stream=True
            ):
                print(chunk)
    """

    chat: AsyncChatResource
    containers: AsyncContainersResource
    files: AsyncFilesResource
    models: AsyncModelsResource
    evaluators: AsyncEvaluatorsResource
    evaluation: AsyncEvaluationResource
    datasets: AsyncDatasetsResource
    optimization: AsyncOptimizationResource

    def __init__(
        self,
        api_key: str | None = None,
        *,
        base_url: str | None = None,
        timeout: float = DEFAULT_TIMEOUT,
        max_retries: int = DEFAULT_MAX_RETRIES,
        http_client: httpx.AsyncClient | None = None,
    ) -> None:
        """Initialize the async Maniac client.

        Args:
            api_key: API key. Falls back to MANIAC_API_KEY environment variable.
            base_url: Base URL. Falls back to MANIAC_BASE_URL or https://platform.maniac.ai.
            timeout: Request timeout in seconds.
            max_retries: Maximum number of retries for failed requests.
            http_client: Custom httpx.AsyncClient instance.
        """
        self._client = AsyncAPIClient(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout,
            max_retries=max_retries,
            http_client=http_client,
        )

        # Initialize resources
        self.chat = AsyncChatResource(self._client)
        self.containers = AsyncContainersResource(self._client)
        self.files = AsyncFilesResource(self._client)
        self.models = AsyncModelsResource(self._client)
        self.evaluators = AsyncEvaluatorsResource(self._client)
        self.evaluation = AsyncEvaluationResource(self._client)
        self.datasets = AsyncDatasetsResource(self._client)
        self.optimization = AsyncOptimizationResource(self._client)

    async def close(self) -> None:
        """Close the HTTP client."""
        await self._client.close()

    async def __aenter__(self) -> AsyncManiac:
        return self

    async def __aexit__(self, *args: Any) -> None:
        await self.close()
