"""
GLM AI 服务
使用智谱 GLM 生成标题和标签
"""

import json
import re
from loguru import logger
from zai import ZhipuAiClient

from app.core.config import settings


class GLMService:
    """GLM AI 服务"""

    def __init__(self):
        self.client = None

    def _get_client(self):
        """获取或创建 ZhipuAI 客户端"""
        if self.client is None:
            if not settings.GLM_API_KEY:
                raise Exception("GLM_API_KEY 未配置")
            self.client = ZhipuAiClient(api_key=settings.GLM_API_KEY)
        return self.client

    async def generate_title_tags(self, text: str) -> dict:
        """
        根据口播文案生成标题和标签

        Args:
            text: 口播文案

        Returns:
            {"title": "标题", "tags": ["标签1", "标签2", ...]}
        """
        prompt = f"""根据以下口播文案，生成一个吸引人的短视频标题、副标题和3个相关标签。

口播文案：
{text}

要求：
1. 标题要简洁有力，能吸引观众点击，不超过10个字
2. 副标题是对标题的补充说明或描述性文字，不超过20个字
3. 标签要与内容相关，便于搜索和推荐，只要3个
4. 标题、副标题和标签必须使用与口播文案相同的语言（如文案是英文就用英文，日文就用日文）

请严格按以下JSON格式返回（不要包含其他内容）：
{{"title": "标题", "secondary_title": "副标题", "tags": ["标签1", "标签2", "标签3"]}}"""

        try:
            client = self._get_client()
            logger.info(f"Calling GLM API with model: {settings.GLM_MODEL}")
            
            # 使用 asyncio.to_thread 包装同步 SDK 调用，避免阻塞事件循环
            import asyncio
            response = await asyncio.to_thread(
                client.chat.completions.create,
                model=settings.GLM_MODEL,
                messages=[{"role": "user", "content": prompt}],
                thinking={"type": "disabled"},  # 禁用思考模式，加快响应
                max_tokens=500,
                temperature=0.7
            )

            # 提取生成的内容
            content = response.choices[0].message.content
            logger.info(f"GLM response (model: {settings.GLM_MODEL}): {content}")

            # 解析 JSON
            result = self._parse_json_response(content)
            return result

        except Exception as e:
            logger.error(f"GLM service error: {e}")
            raise Exception(f"AI 生成失败: {str(e)}")

    async def rewrite_script(self, text: str, custom_prompt: str = None) -> str:
        """
        AI 改写文案

        Args:
            text: 原始文案
            custom_prompt: 自定义提示词，为空则使用默认提示词

        Returns:
            改写后的文案
        """
        if custom_prompt and custom_prompt.strip():
            prompt = f"""{custom_prompt.strip()}

原始文案：
{text}"""
        else:
            prompt = f"""请将以下视频文案进行改写。

原始文案：
{text}

要求：
1. 保持原意，但语气更加自然流畅
2. 适合口播，读起来朗朗上口
3. 字数与原文相当或略微精简
4. 不要返回多余的解释，只返回改写后的正文"""

        try:
            client = self._get_client()
            logger.info(f"Using GLM to rewrite script")

            # 使用 asyncio.to_thread 包装同步 SDK 调用，避免阻塞事件循环
            import asyncio
            response = await asyncio.to_thread(
                client.chat.completions.create,
                model=settings.GLM_MODEL,
                messages=[{"role": "user", "content": prompt}],
                thinking={"type": "disabled"},
                max_tokens=2000,
                temperature=0.8
            )

            content = response.choices[0].message.content
            logger.info("GLM rewrite completed")
            return content.strip()

        except Exception as e:
            logger.error(f"GLM rewrite error: {e}")
            raise Exception(f"AI 改写失败: {str(e)}")



    async def translate_text(self, text: str, target_lang: str) -> str:
        """
        将文案翻译为指定语言

        Args:
            text: 原始文案
            target_lang: 目标语言（如 English, 日本語 等）

        Returns:
            翻译后的文案
        """
        prompt = f"""请将以下文案翻译为{target_lang}。

原文：
{text}

要求：
1. 只返回翻译后的文案，不要添加任何解释或说明
2. 保持原文的语气和风格
3. 翻译要自然流畅，符合目标语言的表达习惯"""

        try:
            client = self._get_client()
            logger.info(f"Using GLM to translate text to {target_lang}")

            import asyncio
            response = await asyncio.to_thread(
                client.chat.completions.create,
                model=settings.GLM_MODEL,
                messages=[{"role": "user", "content": prompt}],
                thinking={"type": "disabled"},
                max_tokens=2000,
                temperature=0.3
            )

            content = response.choices[0].message.content
            logger.info("GLM translation completed")
            return content.strip()

        except Exception as e:
            logger.error(f"GLM translate error: {e}")
            raise Exception(f"AI 翻译失败: {str(e)}")

    def _parse_json_response(self, content: str) -> dict:
        """解析 GLM 返回的 JSON 内容"""
        # 尝试直接解析
        try:
            return json.loads(content)
        except json.JSONDecodeError:
            pass

        # 尝试提取 JSON 块
        json_match = re.search(r'\{[^{}]*"title"[^{}]*"tags"[^{}]*\}', content, re.DOTALL)
        if not json_match:
            json_match = re.search(r'\{[^{}]*"title"[^{}]*"secondary_title"[^{}]*"tags"[^{}]*\}', content, re.DOTALL)
        if json_match:
            try:
                return json.loads(json_match.group())
            except json.JSONDecodeError:
                pass

        # 尝试提取 ```json 代码块
        code_match = re.search(r'```(?:json)?\s*(\{.*?\})\s*```', content, re.DOTALL)
        if code_match:
            try:
                return json.loads(code_match.group(1))
            except json.JSONDecodeError:
                pass

        logger.error(f"Failed to parse GLM response: {content}")
        raise Exception("AI 返回格式解析失败")


# 全局服务实例
glm_service = GLMService()
