#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Content Generator
内容生成器 - 重构版本，使用动态提示词和JSON处理，支持真实的内容格式
"""

import logging
from typing import Dict, Any, List, Optional, Tuple
import json

from ..config import AlgorithmConfig
from ..core import AIService, OutputManager, PromptManager, JSONProcessor
from ..exceptions import ContentGenerationError

logger = logging.getLogger(__name__)


class ContentGenerator:
    """
    内容生成器 - 重构版本
    负责根据主题生成详细的旅游内容，支持真实的字段格式
    """

    def __init__(self, config: AlgorithmConfig):
        """
        初始化内容生成器

        Args:
            config: 算法配置
        """
        self.config = config
        self.ai_service = AIService(config.ai_model)
        self.output_manager = OutputManager(config.output)
        self.prompt_manager = PromptManager(config.prompts, config.resources)
        
        # 初始化JSON处理器
        self.json_processor = JSONProcessor(
            enable_repair=config.content_generation.enable_json_repair,
            max_repair_attempts=config.content_generation.json_repair_attempts
        )
        
        # 获取任务特定的模型配置和字段配置
        self.task_model_config = config.ai_model.get_task_config("content_generation")
        self.field_config = config.content_generation.result_field_mapping.get("content_generation", {})
        
        logger.info(f"内容生成器初始化完成，使用模型参数: {self.task_model_config}")

    async def generate_content(
        self,
        style_content: str,
        demand_content: str,
        object_content: str,
        refer_content: str,
        product_content: str,
        topic: Optional[Dict[str, Any]] = None,
        **kwargs
    ) -> Tuple[str, Dict[str, Any]]:
        """
        生成内容

        Args:
            style_content: 风格内容
            demand_content: 需求内容
            object_content: 对象内容（景区信息）
            refer_content: 参考内容
            product_content: 产品内容
            topic: 主题信息（可选）
            **kwargs: 其他参数

        Returns:
            Tuple[请求ID, 生成的内容字典]

        Raises:
            ContentGenerationError: 生成失败时抛出
        """
        try:
            topic_title = topic.get('title', 'Unknown') if topic else 'Direct Content'
            logger.info(f"开始生成内容，主题: {topic_title}")

            # 1. 构建提示词
            system_prompt = self.prompt_manager.get_prompt("content_generation", "system")
            user_prompt_template = self.prompt_manager.get_prompt("content_generation", "user")
            
            # 格式化用户提示词（根据实际模板格式）
            user_prompt = self.prompt_manager.format_prompt(
                user_prompt_template,
                style_content=style_content,
                demand_content=demand_content,
                object_content=object_content,
                refer_content=refer_content,
                product_content=product_content,
                **kwargs
            )

            # 创建子目录保存内容
            topic_id = topic.get('id', 'direct_content') if topic else 'direct_content'
            subfolder = f"topic_{topic_id}"

            # 保存提示词（如果配置允许）
            if self.config.output.save_prompts:
                self.output_manager.save_text(system_prompt, "system_prompt", "content_generation", subfolder)
                self.output_manager.save_text(user_prompt, "user_prompt", "content_generation", subfolder)

            # 2. 调用AI生成
            content, input_tokens, output_tokens, elapsed_time = await self.ai_service.generate_text(
                system_prompt=system_prompt,
                user_prompt=user_prompt,
                stage="内容生成",
                **self.task_model_config
            )

            # 保存原始响应（如果配置允许）
            if self.config.output.save_raw_responses:
                self.output_manager.save_text(content, "raw_response", "content_generation", subfolder)

            # 3. 解析和结构化内容
            content_data = self._parse_content_result(content, topic)

            # 4. 保存结果
            self.output_manager.save_json(content_data, "content", "", subfolder)
            
            # 5. 保存元数据
            metadata = {
                "topic": topic,
                "materials": {
                    "style_content": style_content[:100] + "..." if len(style_content) > 100 else style_content,
                    "demand_content": demand_content[:100] + "..." if len(demand_content) > 100 else demand_content,
                    "object_content": object_content[:100] + "..." if len(object_content) > 100 else object_content,
                    "product_content": product_content[:100] + "..." if len(product_content) > 100 else product_content
                },
                "field_config": self.field_config,
                "model_config": self.task_model_config,
                "tokens": {
                    "input": input_tokens,
                    "output": output_tokens
                },
                "elapsed_time": elapsed_time
            }
            self.output_manager.save_metadata(metadata, "content_generation", subfolder)

            logger.info(f"内容生成完成，字数: {len(content_data.get('content', ''))}")
            return self.output_manager.run_id, content_data

        except Exception as e:
            error_msg = f"内容生成失败: {str(e)}"
            logger.error(error_msg, exc_info=True)
            raise ContentGenerationError(error_msg)

    def _parse_content_result(self, raw_content: str, topic: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        解析内容生成结果

        Args:
            raw_content: AI原始输出
            topic: 原始主题信息

        Returns:
            解析后的内容字典
        """
        try:
            # 使用JSON处理器解析
            parsed_data = self.json_processor.parse_llm_output(
                raw_output=raw_content,
                expected_fields=self.field_config.get("expected_fields", ["title", "content", "tag"]),
                required_fields=self.field_config.get("required_fields", ["title", "content"])
            )

            # 根据实际提示词返回格式进行标准化
            if isinstance(parsed_data, dict):
                content_data = self._normalize_content_data(parsed_data, topic)
            else:
                # 如果不是预期的字典格式，创建默认结构
                content_data = self._create_fallback_content_data(raw_content, topic)

            return content_data

        except Exception as e:
            logger.warning(f"JSON解析失败，使用回退方案: {e}")
            return self._create_fallback_content_data(raw_content, topic)

    def _normalize_content_data(self, parsed_data: Dict[str, Any], topic: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        标准化内容数据格式

        Args:
            parsed_data: 解析后的数据
            topic: 原始主题信息

        Returns:
            标准化后的内容字典
        """
        # 根据实际提示词的输出格式进行标准化
        normalized_data = {
            # 核心字段（根据实际system.txt的输出格式）
            "title": parsed_data.get("title", ""),
            "content": parsed_data.get("content", ""),
            "tag": parsed_data.get("tag", ""),
            
            # 计算字段
            "word_count": len(parsed_data.get("content", "")),
            "title_length": len(parsed_data.get("title", "")),
            "tag_count": len(parsed_data.get("tag", "").split("#")) - 1 if parsed_data.get("tag") else 0,
            
            # 元数据
            "metadata": {
                "source_topic": topic,
                "generation_config": self.task_model_config,
                "field_config": self.field_config,
                "generated_at": self.output_manager.run_id,
                "format_version": "v1",
                "original_parsed_data": parsed_data
            }
        }

        # 验证关键字段
        if not normalized_data["title"] or not normalized_data["content"]:
            logger.warning("解析结果缺少关键字段，尝试从原始数据提取")
            
            # 尝试其他可能的字段名
            alternative_mappings = {
                "title": ["标题", "主题", "title", "headline"],
                "content": ["内容", "正文", "content", "text", "body"],
                "tag": ["标签", "tag", "tags", "labels"]
            }
            
            for std_field, alternatives in alternative_mappings.items():
                if not normalized_data[std_field]:
                    for alt_field in alternatives:
                        if alt_field in parsed_data and parsed_data[alt_field]:
                            normalized_data[std_field] = parsed_data[alt_field]
                            break

        return normalized_data

    def _create_fallback_content_data(self, raw_content: str, topic: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        创建回退的内容数据（当JSON解析失败时）

        Args:
            raw_content: 原始内容
            topic: 主题信息

        Returns:
            回退的内容字典
        """
        # 尝试从原始文本中提取结构化信息
        extracted_title = ""
        extracted_content = raw_content
        extracted_tag = ""

        # 简单的文本解析逻辑
        lines = raw_content.split('\n')
        if lines:
            first_line = lines[0].strip()
            # 如果第一行较短且不以句号结尾，可能是标题
            if len(first_line) < 100 and not first_line.endswith('。'):
                extracted_title = first_line
                extracted_content = '\n'.join(lines[1:]).strip()

        # 寻找标签（通常包含#符号）
        for line in lines:
            if '#' in line:
                extracted_tag = line.strip()
                break

        return {
            "title": extracted_title,
            "content": extracted_content,
            "tag": extracted_tag,
            "word_count": len(extracted_content),
            "title_length": len(extracted_title),
            "tag_count": extracted_tag.count('#'),
            "metadata": {
                "source_topic": topic,
                "generation_config": self.task_model_config,
                "generated_at": self.output_manager.run_id,
                "format_version": "fallback",
                "parsing_method": "text_extraction",
                "original_raw_content": raw_content[:500] + "..." if len(raw_content) > 500 else raw_content
            }
        }

    async def generate_content_batch(
        self,
        content_requests: List[Dict[str, Any]]
    ) -> Dict[str, Dict[str, Any]]:
        """
        批量生成内容

        Args:
            content_requests: 内容生成请求列表

        Returns:
            批次ID->内容字典的映射
        """
        results = {}
        
        for i, request in enumerate(content_requests):
            try:
                logger.info(f"批量生成内容 {i+1}/{len(content_requests)}")
                
                request_id, content_data = await self.generate_content(**request)
                results[f"request_{i+1}"] = content_data
                
            except Exception as e:
                logger.error(f"批量生成第 {i+1} 项失败: {e}")
                results[f"request_{i+1}"] = {"error": str(e)}
        
        return results

    async def test_generation(self) -> bool:
        """
        测试内容生成功能

        Returns:
            测试是否成功
        """
        try:
            test_materials = {
                "style_content": "攻略风格文案",
                "demand_content": "年轻人周末游需求",
                "object_content": "上海外滩景区信息",
                "refer_content": "参考文案范例",
                "product_content": "外滩一日游产品"
            }
            
            _, content_data = await self.generate_content(**test_materials)
            return len(content_data.get('content', '')) > 50
            
        except Exception as e:
            logger.error(f"内容生成测试失败: {e}")
            return False

    def get_generation_stats(self) -> Dict[str, Any]:
        """
        获取生成统计信息

        Returns:
            统计信息字典
        """
        return {
            "task_model_config": self.task_model_config,
            "field_config": self.field_config,
            "output_directory": str(self.output_manager.run_output_dir),
            "ai_model_info": self.ai_service.get_model_info(),
            "prompt_templates": self.prompt_manager.get_available_templates().get("content_generation", {}),
            "json_processor_enabled": self.json_processor.enable_repair,
            "content_config": {
                "enable_auto_judge": self.config.content_generation.enable_auto_judge,
                "judge_threshold": self.config.content_generation.judge_threshold
            }
        } 