import json
from typing import Any, Dict, Iterator

from ..base_client import BaseClient
from ..sse_parser import parse_sse


class Chat:
    """Chat completions supporting multiple provider formats."""

    def __init__(self, client: BaseClient):
        self._client = client

    # ---- OpenAI-compatible: POST /v1/chat/completions ----

    def completions(self, **kwargs) -> Dict[str, Any]:
        """OpenAI-compatible chat completions.

        Works with GPT, Claude, Doubao, DeepSeek, Qwen, Grok, Gemini (compat),
        MiniMax, Kimi, etc.
        """
        if kwargs.get("stream"):
            return self._stream_completions(**kwargs)
        return self._client.post("/v1/chat/completions", kwargs)

    def _stream_completions(self, **kwargs) -> Iterator[Dict[str, Any]]:
        with self._client.streaming_request("POST", "/v1/chat/completions", kwargs) as response:
            for event in parse_sse(response):
                try:
                    yield json.loads(event["data"])
                except (json.JSONDecodeError, KeyError):
                    pass

    # ---- Anthropic native: POST /v1/messages ----

    def messages(self, **kwargs) -> Any:
        """Anthropic Messages API for Claude models."""
        if kwargs.get("stream"):
            return self._stream_messages(**kwargs)
        return self._client.post("/v1/messages", kwargs)

    def _stream_messages(self, **kwargs) -> Iterator[Dict[str, Any]]:
        with self._client.streaming_request("POST", "/v1/messages", kwargs) as response:
            yield from parse_sse(response)

    # ---- Doubao Responses: POST /v1/responses ----

    def responses(self, **kwargs) -> Any:
        """Doubao Responses API."""
        if kwargs.get("stream"):
            return self._stream_responses(**kwargs)
        return self._client.post("/v1/responses", kwargs)

    def _stream_responses(self, **kwargs) -> Iterator[Dict[str, Any]]:
        with self._client.streaming_request("POST", "/v1/responses", kwargs) as response:
            yield from parse_sse(response)

    # ---- Gemini native: POST /v1beta/models/{model}:generateContent ----

    def gemini(self, model: str, **kwargs) -> Any:
        """Google Gemini native API."""
        stream = kwargs.pop("stream", False)
        action = "streamGenerateContent" if stream else "generateContent"
        endpoint = f"/v1beta/models/{model}:{action}"

        if stream:
            return self._stream_gemini(endpoint, kwargs)
        return self._client.post(endpoint, kwargs)

    def _stream_gemini(self, endpoint: str, body: dict) -> Iterator[Dict[str, Any]]:
        with self._client.streaming_request("POST", endpoint, body) as response:
            yield from parse_sse(response)
