"""
Coze AI对话服务
"""
import logging
from typing import Optional
from cozepy import Coze, COZE_CN_BASE_URL, Message
from cozepy.exception import CozeError, CozeAPIError

from app.core.config import settings
from app.services.ai.coze.client import get_auth_manager

# 注意：不再直接使用 TokenAuth，统一通过 get_auth_manager() 管理认证

logger = logging.getLogger(__name__)


class CozeService:
    """Coze对话服务"""
    
    def __init__(self):
        """初始化Coze客户端"""
        if not settings.COZE_PRACTICE_BOT_ID:
            raise ValueError("COZE_PRACTICE_BOT_ID 未配置")
        
        self.bot_id = settings.COZE_PRACTICE_BOT_ID
        self._auth_manager = get_auth_manager()
        
        logger.info(
            f"CozeService初始化成功，Bot ID={self.bot_id}, "
            f"Base URL={COZE_CN_BASE_URL}"
        )
    
    @property
    def client(self) -> Coze:
        """获取Coze客户端（每次获取确保OAuth token有效）"""
        return self._auth_manager.get_client(force_new=True)
    
    def build_scene_prompt(
        self,
        scene_name: str,
        scene_background: str,
        scene_ai_role: str,
        scene_objectives: list,
        scene_keywords: Optional[list] = None,
        scene_description: Optional[str] = None,
        user_message: str = ""
    ) -> str:
        """
        构建场景提示词（Markdown格式）
        
        参数：
            scene_name: 场景名称
            scene_background: 场景背景
            scene_ai_role: AI角色描述
            scene_objectives: 练习目标列表
            scene_keywords: 关键词列表
            scene_description: 场景描述（可选）
            user_message: 用户第一句话
            
        返回：
            完整的场景提示词（Markdown格式）
        """
        # 构建练习目标
        objectives_text = "\n".join(
            f"{i+1}. {obj}" for i, obj in enumerate(scene_objectives)
        )
        
        # 构建关键词
        keywords_text = ", ".join(scene_keywords) if scene_keywords else ""
        
        # 构建完整提示词
        prompt = f"""# 陪练场景设定

## 场景名称
{scene_name}
"""
        
        # 添加场景描述（如果有）
        if scene_description:
            prompt += f"""
## 场景描述
{scene_description}
"""
        
        prompt += f"""
## 场景背景
{scene_background}

## AI角色要求
{scene_ai_role}

## 练习目标
{objectives_text}
"""
        
        # 添加关键词（如果有）
        if keywords_text:
            prompt += f"""
## 关键词
{keywords_text}
"""
        
        prompt += f"""
---

现在开始陪练对话。请你严格按照上述场景设定扮演角色，与学员进行实战对话练习。
不要提及"场景设定"或"角色扮演"等元信息，直接进入角色开始对话。

学员的第一句话：{user_message}
"""
        
        return prompt
    
    def create_stream_chat(
        self,
        user_id: str,
        message: str,
        conversation_id: Optional[str] = None
    ):
        """
        创建流式对话
        
        参数：
            user_id: 用户ID
            message: 消息内容
            conversation_id: 对话ID（续接对话时使用）
            
        返回：
            Coze流式对话迭代器
        """
        try:
            logger.info(
                f"创建Coze流式对话，user_id={user_id}, "
                f"conversation_id={conversation_id}, "
                f"message_length={len(message)}"
            )
            
            stream = self.client.chat.stream(
                bot_id=self.bot_id,
                user_id=user_id,
                additional_messages=[Message.build_user_question_text(message)],
                conversation_id=conversation_id
            )
            
            # 记录LogID用于排查问题
            if hasattr(stream, 'response') and hasattr(stream.response, 'logid'):
                logger.info(f"Coze对话创建成功，logid={stream.response.logid}")
            
            return stream
            
        except (CozeError, CozeAPIError) as e:
            logger.error(f"Coze API调用失败: {e}")
            raise
        except Exception as e:
            logger.error(f"创建Coze对话失败: {e}")
            raise
    
    def cancel_chat(self, conversation_id: str, chat_id: str):
        """
        中断对话
        
        参数：
            conversation_id: 对话ID
            chat_id: 聊天ID
        """
        try:
            logger.info(f"中断Coze对话，conversation_id={conversation_id}, chat_id={chat_id}")
            
            result = self.client.chat.cancel(
                conversation_id=conversation_id,
                chat_id=chat_id
            )
            
            logger.info(f"对话中断成功")
            return result
            
        except (CozeError, CozeAPIError) as e:
            logger.error(f"中断对话失败: {e}")
            raise
        except Exception as e:
            logger.error(f"中断对话异常: {e}")
            raise


# 单例模式
_coze_service: Optional[CozeService] = None


def get_coze_service() -> CozeService:
    """
    获取CozeService单例
    
    用于FastAPI依赖注入
    """
    global _coze_service
    if _coze_service is None:
        _coze_service = CozeService()
    return _coze_service

