import asyncio
import base64
import io
from typing import List, Optional

import PIL.Image
from google import genai
from google.api_core.exceptions import GoogleAPIError
from google.genai import types
from loguru import logger


class GoogleAPI:
    @property
    def provider_name(self) -> str:
        return "gemini"

    @property
    def supported_models(self) -> List[str]:
        return [
            "gemini-2.5-flash",
            "gemini-2.5-pro",
            "gemini-2.0-flash"
        ]

    def _image_to_base64(self, img: PIL.Image.Image) -> str:
        """将PIL图片转换为base64编码"""
        img_buffer = io.BytesIO()
        img.save(img_buffer, format='JPEG', quality=85)
        img_bytes = img_buffer.getvalue()
        return base64.b64encode(img_bytes).decode('utf-8')

    async def _make_api_call(self, model_name: str, prompt: str, system_prompt: str, temperature: float = 1.0,
                             text_api_key: str = None) -> str:
        """执行原生Gemini API调用，包含重试机制"""
        from app.config import config

        max_retries = config.app.get('llm_max_retries', 3)
        base_timeout = config.app.get('llm_vision_timeout', 120)

        for attempt in range(max_retries):
            try:
                # 根据尝试次数调整超时时间
                timeout = base_timeout * (attempt + 1)
                logger.debug(f"Gemini API调用尝试 {attempt + 1}/{max_retries}，超时设置: {timeout}秒")
                client = genai.Client(api_key=text_api_key)
                response = client.models.generate_content_stream(
                    model=model_name,
                    contents=[prompt],
                    config=types.GenerateContentConfig(
                        response_mime_type="application/json",
                        system_instruction=system_prompt,
                        temperature=temperature
                    )
                )
                data = ''
                for chunk in response:
                    text = chunk.text
                    if text is not None:
                        data += chunk.text
                    print(chunk.text, end="")
                return data
            except Exception as e:
                logger.error(f"Gemini API失败: {str(e)}")
                if attempt < max_retries - 1:
                    wait_time = 15 * (attempt + 1)
                    logger.warning(f"Gemini API请求超时，等待 {wait_time} 秒后重试")
                    await asyncio.sleep(wait_time)
                    continue
                else:
                    raise GoogleAPIError("Gemini API请求超时，已达到最大重试次数")

        # 如果所有重试都失败了
        raise GoogleAPIError("Gemini API调用失败，已达到最大重试次数")

    async def generate_text(self,
                            model_name: str,
                            prompt: str,
                            system_prompt: Optional[str] = None,
                            temperature: float = 1.0,
                            text_api_key: str = None) -> str:

        # 发送API请求
        response_data = await self._make_api_call(model_name, prompt, system_prompt, temperature, text_api_key)

        # 解析响应
        return response_data

    async def analyze_subtitle(self, subtitle_content: str,
                               model_name: str = None,
                               temperature: float = 1.0,
                               text_api_key: str = None) -> str:

        try:
            # 构建分析提示词
            system_prompt = "你是一位专业的剧本分析师和剧情概括助手。请仔细分析字幕内容，提取关键剧情信息。"

            # 生成分析结果
            result = await self.generate_text(
                prompt=subtitle_content,
                system_prompt=system_prompt,
                model_name=model_name,
                temperature=temperature,
                text_api_key=text_api_key
            )

            return result

        except Exception as e:
            logger.error(f"字幕分析失败: {str(e)}")
            raise GoogleAPIError(f"字幕分析失败: {str(e)}")
