"""
Gemini Chat Handler

处理 Gemini API 格式的请求
"""

from typing import Any, Dict, Optional

from src.api.handlers.base.chat_handler_base import ChatHandlerBase


class GeminiChatHandler(ChatHandlerBase):
    """
    Gemini Chat Handler - 处理 Google Gemini API 格式的请求

    格式特点:
    - 使用 promptTokenCount / candidatesTokenCount
    - 支持 cachedContentTokenCount
    - 请求格式: GeminiRequest
    - 响应格式: JSON 数组流（非 SSE）
    """

    FORMAT_ID = "GEMINI"

    def extract_model_from_request(
        self,
        request_body: Dict[str, Any],
        path_params: Optional[Dict[str, Any]] = None,
    ) -> str:
        """
        从请求中提取模型名 - Gemini Chat 格式实现

        Gemini Chat 模式下，model 在请求体中（经过转换后的 GeminiRequest）。
        与 Gemini CLI 不同，CLI 模式的 model 在 URL 路径中。

        Args:
            request_body: 请求体
            path_params: URL 路径参数（Chat 模式通常不使用）

        Returns:
            模型名
        """
        # 优先从请求体获取，其次从 path_params
        model = request_body.get("model")
        if model:
            return str(model)
        if path_params and "model" in path_params:
            return str(path_params["model"])
        return "unknown"

    async def _convert_request(self, request):
        """
        将请求转换为 Gemini 格式

        支持自动转换:
        - Claude 格式 → Gemini 格式
        - OpenAI 格式 → Gemini 格式

        Args:
            request: 原始请求对象（可能是 Gemini/Claude/OpenAI 格式）

        Returns:
            GeminiRequest 对象
        """
        from src.api.handlers.gemini.converter import (
            ClaudeToGeminiConverter,
            OpenAIToGeminiConverter,
        )
        from src.models.claude import ClaudeMessagesRequest
        from src.models.gemini import GeminiRequest
        from src.models.openai import OpenAIRequest

        # 如果已经是 Gemini 格式，直接返回
        if isinstance(request, GeminiRequest):
            return request

        # 如果是 Claude 格式，转换为 Gemini 格式
        if isinstance(request, ClaudeMessagesRequest):
            converter = ClaudeToGeminiConverter()
            gemini_dict = converter.convert_request(request.model_dump())
            return GeminiRequest(**gemini_dict)

        # 如果是 OpenAI 格式，转换为 Gemini 格式
        if isinstance(request, OpenAIRequest):
            converter = OpenAIToGeminiConverter()
            gemini_dict = converter.convert_request(request.model_dump())
            return GeminiRequest(**gemini_dict)

        # 如果是字典，根据内容判断格式并转换
        if isinstance(request, dict):
            # 检测 Gemini 格式特征: contents 字段
            if "contents" in request:
                return GeminiRequest(**request)

            # 检测 Claude 格式特征: messages + 没有 choices
            if "messages" in request and "choices" not in request:
                # 进一步区分 Claude 和 OpenAI
                # Claude 使用 max_tokens，OpenAI 也可能有
                # Claude 的 messages[].content 可以是数组，OpenAI 通常是字符串
                messages = request.get("messages", [])
                if messages and isinstance(messages[0].get("content"), list):
                    # 可能是 Claude 格式
                    converter = ClaudeToGeminiConverter()
                    gemini_dict = converter.convert_request(request)
                    return GeminiRequest(**gemini_dict)
                else:
                    # 可能是 OpenAI 格式
                    converter = OpenAIToGeminiConverter()
                    gemini_dict = converter.convert_request(request)
                    return GeminiRequest(**gemini_dict)

            # 默认尝试作为 Gemini 格式
            return GeminiRequest(**request)

        return request

    def _extract_usage(self, response: Dict) -> Dict[str, int]:
        """
        从 Gemini 响应中提取 token 使用情况

        调用 GeminiStreamParser.extract_usage 作为单一实现源
        """
        from src.api.handlers.gemini.stream_parser import GeminiStreamParser

        usage = GeminiStreamParser().extract_usage(response)

        if not usage:
            return {
                "input_tokens": 0,
                "output_tokens": 0,
                "cache_creation_input_tokens": 0,
                "cache_read_input_tokens": 0,
            }

        return {
            "input_tokens": usage.get("input_tokens", 0),
            "output_tokens": usage.get("output_tokens", 0),
            "cache_creation_input_tokens": 0,  # Gemini 不区分缓存创建
            "cache_read_input_tokens": usage.get("cached_tokens", 0),
        }

    def _normalize_response(self, response: Dict) -> Dict:
        """
        规范化 Gemini 响应

        Args:
            response: 原始响应

        Returns:
            规范化后的响应
        """
        # 作为中转站，直接透传响应，不做标准化处理
        return response
