"""
剧集创作 Agent

固定工作流：
1. 加载全局上下文和历史记忆
2. 结构分析
3. 大纲生成
4. 对话创作
5. 一致性审核
6. 更新记忆系统
"""
from typing import Dict, Any, Optional
from datetime import datetime
from app.models.project import SeriesProject, Episode, EpisodeIssue, TaskType
from app.core.skills.skill_manager import get_skill_manager
from app.core.skills.skill_resolver import get_skill_resolver
from app.core.llm.glm_client import get_glm_client
from app.utils.logger import get_logger
import json

logger = get_logger(__name__)


class SeriesCreationAgent:
    """
    剧集创作 Agent

    负责执行完整的剧集创作工作流
    """

    def __init__(self):
        self.skill_manager = get_skill_manager()
        self.skill_resolver = get_skill_resolver()
        self.glm_client = get_glm_client()
        logger.info("剧集创作 Agent 初始化完成")

    async def execute_episode(
        self,
        project: SeriesProject,
        episode_number: int,
        title: str = ""
    ) -> Episode:
        """
        执行单集创作

        Args:
            project: 剧集项目
            episode_number: 集数
            title: 集标题（可选）

        Returns:
            创作的 Episode 对象
        """
        logger.info(f"开始创作 EP{episode_number}")

        # 创建 Episode 对象
        episode = Episode(
            projectId=project.id,
            number=episode_number,
            title=title or f"第{episode_number}集",
            status="writing"
        )

        try:
            # ============================================
            # 阶段 1: 结构分析
            # ============================================
            logger.info(f"EP{episode_number} - 阶段 1: 结构分析")
            structure = await self._analyze_structure(project, episode_number)
            episode.structure = structure

            # ============================================
            # 阶段 2: 大纲生成
            # ============================================
            logger.info(f"EP{episode_number} - 阶段 2: 大纲生成")
            outline = await self._generate_outline(project, episode_number, structure)
            episode.outline = outline

            # ============================================
            # 阶段 3: 对话创作（核心）
            # ============================================
            logger.info(f"EP{episode_number} - 阶段 3: 对话创作")
            content = await self._write_dialogue(project, episode_number, outline)
            episode.content = content

            # ============================================
            # 阶段 4: 一致性审核
            # ============================================
            logger.info(f"EP{episode_number} - 阶段 4: 一致性审核")
            review = await self._review_consistency(project, episode_number, content)
            episode.qualityScore = review.get("score", 0)
            episode.issues = review.get("issues", [])

            # ============================================
            # 阶段 5: 更新记忆系统
            # ============================================
            logger.info(f"EP{episode_number} - 阶段 5: 更新记忆系统")
            await self._update_memory(project, episode_number, content)

            # 完成
            episode.status = "completed"
            episode.completedAt = datetime.now()
            logger.info(f"EP{episode_number} 创作完成，质量分数: {episode.qualityScore}")

        except Exception as e:
            logger.error(f"EP{episode_number} 创作失败: {str(e)}")
            episode.status = "needs-review"
            episode.issues = [
                EpisodeIssue(
                    type="execution_error",
                    description=str(e),
                    severity="high"
                )
            ]

        return episode

    async def _analyze_structure(
        self,
        project: SeriesProject,
        episode_number: int
    ) -> Dict[str, Any]:
        """分析本集结构"""
        # 使用默认的结构分析逻辑
        structure = {
            "episodeNumber": episode_number,
            "scenes": [],
            "keyEvents": []
        }
        return structure

    async def _generate_outline(
        self,
        project: SeriesProject,
        episode_number: int,
        structure: Dict[str, Any]
    ) -> str:
        """生成剧集大纲"""
        # 构建提示词
        context = self._build_context(project, episode_number)

        prompt = f"""请为《{project.name}》创作第 {episode_number} 集的大纲。

{context}

要求：
1. 大纲应包含 3-5 个场景
2. 每个场景简要描述情节
3. 字数 200-300 字
"""

        try:
            # 使用 SkillResolver 解析 Skills
            resolved_skills = await self.skill_resolver.resolve_skills_for_task(
                project=project,
                task_type=TaskType.OUTLINE,
                episode_number=episode_number
            )

            if resolved_skills:
                skill_data = resolved_skills[0]
                skill = skill_data["skill"]
                parameters = skill_data["parameters"]
                references = skill_data["references"]

                logger.info(f"EP{episode_number} 大纲生成使用 Skill: {skill.id}")

                return await self.glm_client.chat_with_skill(
                    skill_behavior=skill.behavior_guide,
                    user_input=prompt,
                    context=context,
                    temperature=parameters.get("temperature", 0.7),
                    references=references if references else None
                )

            # 回退到基本调用
            response = await self.glm_client.chat(
                messages=[
                    {"role": "system", "content": "你是剧集创作专家。"},
                    {"role": "user", "content": prompt}
                ]
            )
            return response["choices"][0]["message"]["content"]

        except Exception as e:
            logger.error(f"大纲生成失败: {str(e)}")
            return f"第{episode_number}集大纲：本集讲述..."

    async def _write_dialogue(
        self,
        project: SeriesProject,
        episode_number: int,
        outline: str
    ) -> str:
        """创作对话内容（核心阶段）"""
        context = self._build_context(project, episode_number)

        prompt = f"""请根据以下大纲创作第 {episode_number} 集的完整剧本：

大纲：
{outline}

{context}

要求：
1. 使用【场景】标记场景开始
2. 使用【人物】标记出场人物
3. 包含对话和动作描写
4. 保持人物性格和说话风格一致
"""

        try:
            # 使用 SkillResolver 解析 Skills
            resolved_skills = await self.skill_resolver.resolve_skills_for_task(
                project=project,
                task_type=TaskType.DIALOGUE,
                episode_number=episode_number
            )

            if not resolved_skills:
                # 回退方案
                logger.warning(f"EP{episode_number} 未找到对话创作 Skill，使用默认方案")
                response = await self.glm_client.chat(
                    messages=[
                        {"role": "system", "content": "你是专业的剧集编剧。"},
                        {"role": "user", "content": prompt}
                    ],
                    temperature=0.7
                )
                return response["choices"][0]["message"]["content"]

            # 使用第一个（最高优先级）Skill
            skill_data = resolved_skills[0]
            skill = skill_data["skill"]
            parameters = skill_data["parameters"]
            references = skill_data["references"]

            logger.info(
                f"EP{episode_number} 对话创作使用 Skill: {skill.id}, "
                f"参数: {parameters}, 参考文件数: {len(references)}"
            )

            # 使用 Skill 行为指导 + 参考文件
            return await self.glm_client.chat_with_skill(
                skill_behavior=skill.behavior_guide,
                user_input=prompt,
                context=context,
                temperature=parameters.get("temperature", 0.7),
                references=references if references else None
            )

        except Exception as e:
            logger.error(f"对话创作失败: {str(e)}")
            return f"第{episode_number}集内容创作失败: {str(e)}"

    async def _review_consistency(
        self,
        project: SeriesProject,
        episode_number: int,
        content: str
    ) -> Dict[str, Any]:
        """审核一致性"""
        try:
            from app.core.memory.memory_manager import get_memory_manager
            from app.models.memory import EnhancedMemory

            memory_manager = get_memory_manager()

            # 转换为 EnhancedMemory
            enhanced_memory = memory_manager._convert_to_enhanced_memory(project.memory)

            # 使用 MemoryManager 检查一致性
            issues = await memory_manager.check_consistency(
                episode_content=content,
                episode_number=episode_number,
                memory=enhanced_memory
            )

            # 计算质量分数
            high_issues = [i for i in issues if i.severity.value == "high"]
            medium_issues = [i for i in issues if i.severity.value == "medium"]

            score = 100 - (len(high_issues) * 15) - (len(medium_issues) * 5)
            score = max(0, min(100, score))

            # 将问题转换为 EpisodeIssue 格式
            episode_issues = [
                EpisodeIssue(
                    type=issue.type,
                    description=issue.description,
                    severity=issue.severity.value,
                    suggestion=issue.suggestion
                )
                for issue in issues
            ]

            logger.info(
                f"一致性审核完成: 分数={score}, "
                f"问题={len(issues)} (高={len(high_issues)}, 中={len(medium_issues)})"
            )

            return {
                "score": score,
                "issues": episode_issues
            }

        except Exception as e:
            logger.error(f"一致性审核失败: {str(e)}")
            return {"score": 80, "issues": []}

    async def _update_memory(
        self,
        project: SeriesProject,
        episode_number: int,
        content: str
    ):
        """更新记忆系统"""
        from app.core.memory.memory_manager import get_memory_manager

        # 创建 Episode 对象
        episode = Episode(
            projectId=project.id,
            number=episode_number,
            title=f"第{episode_number}集",
            status="completed",
            content=content,
            completedAt=datetime.now()
        )

        # 调用 MemoryManager 更新记忆
        memory_manager = get_memory_manager()
        result = await memory_manager.update_memory_from_episode(project, episode)

        logger.info(
            f"记忆更新完成: 事件={result.events_extracted}, "
            f"伏笔={result.foreshadowing_detected}, "
            f"待收线={result.threads_suggested}, "
            f"角色状态={result.character_states_updated}, "
            f"一致性问题={result.consistency_issues_found}"
        )

        return result

    def _build_context(
        self,
        project: SeriesProject,
        episode_number: int
    ) -> str:
        """构建上下文字符串"""
        context_parts = []

        # 世界观
        if project.globalContext.worldSetting:
            context_parts.append(f"世界观：{project.globalContext.worldSetting}")

        # 人物设定
        if project.globalContext.characterProfiles:
            context_parts.append("\n人物设定：")
            for char_id, char in project.globalContext.characterProfiles.items():
                context_parts.append(f"- {char.name}：{char.personality}，说话风格：{char.speechStyle}")

        # 历史记忆（最近3集）
        if project.memory.eventTimeline:
            context_parts.append("\n历史剧情：")
            recent_events = project.memory.eventTimeline[-3:]
            for event in recent_events:
                context_parts.append(f"- {event.get('event', '')}")

        return "\n".join(context_parts)


# 全局单例
_agent_instance: Optional[SeriesCreationAgent] = None


def get_series_agent() -> SeriesCreationAgent:
    """获取剧集创作 Agent 单例"""
    global _agent_instance
    if _agent_instance is None:
        _agent_instance = SeriesCreationAgent()
    return _agent_instance
