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

"""
Text Generator for Posters
海报文本生成器 - 负责生成海报所需的文案内容，支持Vibrant模板格式
"""

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

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

logger = logging.getLogger(__name__)


class TextGenerator:
    """
    海报文本生成器
    使用AI模型为海报生成适合的文案内容，特别支持Vibrant模板的字段结构
    """

    def __init__(
        self, 
        config: AlgorithmConfig, 
        ai_service: AIService,
        prompt_manager: PromptManager,
        json_processor: JSONProcessor
    ):
        """
        初始化文本生成器

        Args:
            config: 算法配置
            ai_service: AI服务
            prompt_manager: 提示词管理器
            json_processor: JSON处理器
        """
        self.config = config
        self.ai_service = ai_service
        self.prompt_manager = prompt_manager
        self.json_processor = json_processor
        
        # 获取任务特定的模型配置
        self.task_model_config = config.ai_model.get_task_config("poster_generation")
        
        logger.info("海报文本生成器初始化完成")

    async def generate_poster_content(
        self,
        topic_info: str,
        style: str = "活泼有趣",
        target_audience: str = "年轻旅行者",
        poster_type: str = "旅游宣传",
        **kwargs
    ) -> Dict[str, Any]:
        """
        生成海报文案内容

        Args:
            topic_info: 主题信息
            style: 文案风格
            target_audience: 目标受众
            poster_type: 海报类型
            **kwargs: 其他参数

        Returns:
            生成的海报内容字典

        Raises:
            ContentGenerationError: 生成失败时抛出
        """
        try:
            logger.info(f"开始生成海报文案，主题: {topic_info}")

            # 1. 构建提示词
            system_prompt = self._get_poster_system_prompt()
            user_prompt = self._build_user_prompt(
                topic_info=topic_info,
                style=style,
                target_audience=target_audience,
                poster_type=poster_type,
                **kwargs
            )

            # 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
            )

            # 3. 解析结果
            poster_content = self._parse_poster_content(content)

            # 4. 验证和增强内容
            validated_content = self._validate_and_enhance_content(poster_content, topic_info)

            logger.info("海报文案生成完成")
            return validated_content

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

    async def generate_vibrant_content(
        self,
        scenic_info: str,
        product_info: str,
        tweet_info: str = "",
        **kwargs
    ) -> Dict[str, Any]:
        """
        专门为Vibrant模板生成内容

        Args:
            scenic_info: 景区信息
            product_info: 产品信息
            tweet_info: 推文信息
            **kwargs: 其他参数

        Returns:
            符合Vibrant模板结构的内容字典

        Raises:
            ContentGenerationError: 生成失败时抛出
        """
        try:
            logger.info("开始生成Vibrant模板专用内容")

            # 1. 构建Vibrant专用提示词
            system_prompt = self._get_vibrant_system_prompt()
            user_prompt = self._build_vibrant_user_prompt(scenic_info, product_info, tweet_info)

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

            # 3. 解析并验证Vibrant格式
            vibrant_content = self._parse_vibrant_content(content)

            logger.info("Vibrant模板内容生成完成")
            return vibrant_content

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

    def _get_poster_system_prompt(self) -> str:
        """获取海报生成的系统提示词"""
        try:
            # 尝试从文件加载
            return self.prompt_manager.get_prompt("poster_generation", "system")
        except:
            # 使用默认提示词
            return """你是一个专业的海报文案创作者，专门为旅游、美食、生活方式等主题创作吸引人的海报文案。

你的任务是根据给定的主题信息，创作适合海报展示的文案内容，包括：
1. 吸引人的标题（简洁有力，15字以内）
2. 核心内容描述（生动形象，突出亮点）
3. 相关标签（3-5个关键词）
4. 行动召唤语句（激发用户行动）

要求：
- 文案要有感染力和画面感
- 适合目标受众的语言风格
- 突出主题的独特价值
- 符合海报的视觉传达需求"""

    def _get_vibrant_system_prompt(self) -> str:
        """获取Vibrant模板专用的系统提示词"""
        return """你是一名专业的海报设计师，专门设计宣传海报。你现在要根据用户提供的信息，生成适合Vibrant模板的海报内容。

## Vibrant模板特点：
- 单图背景，毛玻璃渐变效果
- 两栏布局（左栏内容，右栏价格）
- 适合展示套餐内容和价格信息

## 你需要生成的数据结构包含以下字段：

**必填字段：**
1. `title`: 主标题（8-12字符，体现产品特色）
2. `slogan`: 副标题/宣传语（10-20字符，吸引人的描述）
3. `price`: 价格数字（纯数字，不含符号），如果材料中没有价格，则用"欢迎咨询"替代
4. `ticket_type`: 票种类型（如"成人票"、"套餐票"、"夜场票"等）
5. `content_button`: 内容按钮文字（通常为"套餐内容"、"包含项目"等）
6. `content_items`: 套餐内容列表（3-5个项目，每项5-15字符，不要只包含项目名称，要做合适的美化，可以适当省略）

**可选字段：**
7. `remarks`: 备注信息（1-3条，每条10-20字符）
8. `tag`: 标签（1条, 如"#限时优惠"等）
9. `pagination`: 分页信息（如"1/3"，可为空）

## 内容创作要求：
1. 套餐内容要具体实用：明确说明包含的服务、时间、数量
2. 价格要有吸引力：突出性价比和优惠信息

## 输出格式：
请严格按照JSON格式输出，不要有任何额外内容。"""

    def _build_user_prompt(
        self,
        topic_info: str,
        style: str,
        target_audience: str,
        poster_type: str,
        **kwargs
    ) -> str:
        """构建用户提示词"""
        
        user_prompt_template = """请为以下主题创作海报文案：

### 主题信息
{topic_info}

### 创作要求
- 文案风格：{style}
- 目标受众：{target_audience}
- 海报类型：{poster_type}

### 额外要求
{additional_requirements}

请按照以下JSON格式输出：
{
    "title": "海报标题（15字以内）",
    "content": "主要内容描述",
    "tags": ["标签1", "标签2", "标签3"],
    "call_to_action": "行动召唤语句"
}"""

        additional_requirements = self._format_additional_requirements(kwargs)
        
        return user_prompt_template.format(
            topic_info=topic_info,
            style=style,
            target_audience=target_audience,
            poster_type=poster_type,
            additional_requirements=additional_requirements
        )

    def _build_vibrant_user_prompt(self, scenic_info: str, product_info: str, tweet_info: str) -> str:
        """构建Vibrant模板专用的用户提示词"""
        return f"""请根据以下信息，生成适合在旅游海报上展示的文案：

## 景区信息
{scenic_info}

## 产品信息
{product_info}

## 推文信息
{tweet_info if tweet_info else "无"}

请提取关键信息并整合成一个JSON对象，包含title、slogan、price、ticket_type、content_items、remarks和tag字段。"""

    def _format_additional_requirements(self, kwargs: Dict[str, Any]) -> str:
        """格式化额外要求"""
        requirements = []
        
        if kwargs.get("color_theme"):
            requirements.append(f"- 配色主题：{kwargs['color_theme']}")
        
        if kwargs.get("mood"):
            requirements.append(f"- 情感氛围：{kwargs['mood']}")
        
        if kwargs.get("key_points"):
            key_points = kwargs['key_points']
            if isinstance(key_points, list):
                requirements.append(f"- 重点突出：{', '.join(key_points)}")
            else:
                requirements.append(f"- 重点突出：{key_points}")
        
        if kwargs.get("length_preference"):
            requirements.append(f"- 文案长度：{kwargs['length_preference']}")

        return "\n".join(requirements) if requirements else "无特殊要求"

    def _parse_poster_content(self, raw_content: str) -> Dict[str, Any]:
        """解析海报内容生成结果"""
        try:
            # 使用JSON处理器解析
            parsed_data = self.json_processor.parse_llm_output(
                raw_output=raw_content,
                expected_fields=["title", "content", "tags", "call_to_action"],
                required_fields=["title", "content"]
            )
            
            if isinstance(parsed_data, dict):
                return parsed_data
            else:
                logger.warning("解析结果不是字典格式，使用回退方案")
                return self._extract_content_from_text(raw_content)
                
        except Exception as e:
            logger.warning(f"JSON解析失败，使用文本提取: {e}")
            return self._extract_content_from_text(raw_content)

    def _parse_vibrant_content(self, raw_content: str) -> Dict[str, Any]:
        """解析Vibrant模板专用内容"""
        try:
            # 使用JSON处理器解析，指定Vibrant的字段
            expected_fields = ["title", "slogan", "price", "ticket_type", "content_button", "content_items"]
            required_fields = ["title", "slogan", "price", "ticket_type", "content_items"]
            
            parsed_data = self.json_processor.parse_llm_output(
                raw_output=raw_content,
                expected_fields=expected_fields + ["remarks", "tag", "pagination"],
                required_fields=required_fields
            )
            
            if isinstance(parsed_data, dict):
                return self._normalize_vibrant_content(parsed_data)
            else:
                logger.warning("解析结果不是字典格式，使用回退方案")
                return self._create_fallback_vibrant_content()
                
        except Exception as e:
            logger.warning(f"Vibrant内容解析失败，使用回退方案: {e}")
            return self._create_fallback_vibrant_content()

    def _normalize_vibrant_content(self, parsed_data: Dict[str, Any]) -> Dict[str, Any]:
        """标准化Vibrant内容格式"""
        normalized = {
            # 必填字段
            "title": parsed_data.get("title", "精彩旅程"),
            "slogan": parsed_data.get("slogan", "发现世界的美好"),
            "price": str(parsed_data.get("price", "欢迎咨询")),
            "ticket_type": parsed_data.get("ticket_type", "门票"),
            "content_button": parsed_data.get("content_button", "套餐内容"),
            "content_items": parsed_data.get("content_items", ["精彩体验项目"]),
            
            # 可选字段
            "remarks": parsed_data.get("remarks", []),
            "tag": parsed_data.get("tag", ""),
            "pagination": parsed_data.get("pagination", "")
        }
        
        # 确保content_items是列表
        if isinstance(normalized["content_items"], str):
            normalized["content_items"] = [normalized["content_items"]]
        
        # 确保remarks是列表
        if isinstance(normalized["remarks"], str):
            normalized["remarks"] = [normalized["remarks"]]
        
        # 限制列表长度
        normalized["content_items"] = normalized["content_items"][:5]
        normalized["remarks"] = normalized["remarks"][:3]
        
        return normalized

    def _create_fallback_vibrant_content(self) -> Dict[str, Any]:
        """创建Vibrant模板的回退内容"""
        return {
            "title": "精彩旅程体验",
            "slogan": "探索世界的无限可能",
            "price": "欢迎咨询",
            "ticket_type": "体验票",
            "content_button": "套餐内容",
            "content_items": [
                "专业导游服务",
                "精美旅游纪念品",
                "全程保险保障"
            ],
            "remarks": ["请提前预约", "节假日价格另议"],
            "tag": "#精彩体验",
            "pagination": ""
        }

    def _extract_content_from_text(self, text: str) -> Dict[str, Any]:
        """从文本中提取海报内容（回退方案）"""
        lines = text.strip().split('\n')
        
        # 简单的文本解析逻辑
        title = ""
        content = ""
        tags = []
        call_to_action = ""
        
        for line in lines:
            line = line.strip()
            if not line:
                continue
            
            if len(line) <= 20 and not title:
                # 可能是标题
                title = line
            elif '#' in line:
                # 可能是标签
                tags = [tag.strip() for tag in line.replace('#', '').split() if tag.strip()]
            elif not content and len(line) > 10:
                # 可能是主要内容
                content = line
            elif len(line) <= 15 and ('！' in line or '!' in line):
                # 可能是行动召唤
                call_to_action = line

        return {
            "title": title or "精彩旅程",
            "content": content or text[:100],
            "tags": tags or ["旅行", "探索"],
            "call_to_action": call_to_action or "立即体验！"
        }

    def _validate_and_enhance_content(
        self, 
        content: Dict[str, Any], 
        topic_info: str
    ) -> Dict[str, Any]:
        """验证和增强海报内容"""
        
        # 确保所有必需字段存在
        validated_content = {
            "title": content.get("title", "精彩旅程")[:15],  # 限制标题长度
            "content": content.get("content", topic_info),
            "tags": content.get("tags", ["旅行"]),
            "call_to_action": content.get("call_to_action", "立即体验！")
        }
        
        # 确保标签是列表格式
        if isinstance(validated_content["tags"], str):
            validated_content["tags"] = [tag.strip() for tag in validated_content["tags"].split(",")]
        
        # 限制标签数量
        validated_content["tags"] = validated_content["tags"][:5]
        
        # 添加元数据
        validated_content["metadata"] = {
            "word_count": len(validated_content["content"]),
            "tag_count": len(validated_content["tags"]),
            "generated_for": topic_info,
            "generation_config": self.task_model_config
        }
        
        return validated_content

    async def generate_multiple_variations(
        self,
        topic_info: str,
        num_variations: int = 3,
        template_type: str = "general",
        **kwargs
    ) -> List[Dict[str, Any]]:
        """
        生成多个文案变体

        Args:
            topic_info: 主题信息
            num_variations: 变体数量
            template_type: 模板类型 ("general", "vibrant")
            **kwargs: 其他参数

        Returns:
            文案变体列表
        """
        variations = []
        
        styles = ["活泼有趣", "温馨感人", "激情澎湃", "优雅文艺", "简洁干练"]
        
        for i in range(num_variations):
            try:
                # 使用不同的风格
                style = styles[i % len(styles)]
                
                if template_type == "vibrant":
                    # 为Vibrant模板生成内容
                    variation = await self.generate_vibrant_content(
                        scenic_info=kwargs.get("scenic_info", topic_info),
                        product_info=kwargs.get("product_info", ""),
                        tweet_info=kwargs.get("tweet_info", ""),
                        **kwargs
                    )
                else:
                    # 通用海报内容
                    variation = await self.generate_poster_content(
                        topic_info=topic_info,
                        style=style,
                        **kwargs
                    )
                
                variation["variation_id"] = i + 1
                variation["style_used"] = style
                variations.append(variation)
                
            except Exception as e:
                logger.error(f"生成变体 {i+1} 失败: {e}")
                continue
        
        return variations

    def get_style_suggestions(self, poster_type: str, target_audience: str) -> List[str]:
        """
        根据海报类型和目标受众获取风格建议

        Args:
            poster_type: 海报类型
            target_audience: 目标受众

        Returns:
            风格建议列表
        """
        style_mapping = {
            "旅游宣传": {
                "年轻人": ["活泼有趣", "激情澎湃", "个性时尚"],
                "家庭": ["温馨感人", "亲切自然", "安全舒适"],
                "商务人士": ["优雅文艺", "简洁干练", "品质生活"]
            },
            "美食推荐": {
                "年轻人": ["诱人美味", "时尚潮流", "分享快乐"],
                "家庭": ["家常温馨", "营养健康", "团圆美好"],
                "美食爱好者": ["精致品味", "传统文化", "匠心工艺"]
            },
            "活动宣传": {
                "年轻人": ["活力四射", "激情参与", "社交互动"],
                "全年龄": ["欢乐共享", "文化体验", "意义深远"],
                "专业人士": ["高端品质", "网络建设", "知识分享"]
            }
        }
        
        return style_mapping.get(poster_type, {}).get(target_audience, ["活泼有趣", "简洁明快"]) 