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

"""
Poster Generator
海报生成器 - 重构版本，使用配置化系统和动态模板加载
"""

import logging
import random
from typing import List, Dict, Any, Optional, Union, Tuple
from pathlib import Path
from PIL import Image

from ..config import AlgorithmConfig
from ..core import AIService, OutputManager, PromptManager, JSONProcessor
from ..exceptions import PosterGenerationError, ResourceNotFoundError
from .template_manager import TemplateManager
from .text_generator import TextGenerator

logger = logging.getLogger(__name__)


class PosterGenerator:
    """
    海报生成器 - 重构版本
    负责根据文本内容和配置生成海报图像，支持多种模板和风格
    """

    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.template_manager = TemplateManager(config.poster_generation, config.resources)
        self.text_generator = TextGenerator(config, self.ai_service, self.prompt_manager, self.json_processor)
        
        # 获取任务特定的模型配置
        self.task_model_config = config.ai_model.get_task_config("poster_generation")
        
        logger.info(f"海报生成器初始化完成，可用模板: {self.template_manager.get_available_templates()}")

    async def generate_poster(
        self,
        content: Optional[Dict[str, Any]] = None,
        images: Optional[List[Union[str, Image.Image]]] = None,
        template_name: str = "vibrant",
        style_options: Optional[Dict[str, Any]] = None,
        **kwargs
    ) -> Tuple[str, Dict[str, Any]]:
        """
        生成海报

        Args:
            content: 海报文本内容（如果为空，将使用AI生成）
            images: 图像列表（文件路径或PIL图像对象）
            template_name: 模板名称
            style_options: 样式选项
            **kwargs: 其他参数

        Returns:
            Tuple[请求ID, 生成结果]

        Raises:
            PosterGenerationError: 生成失败时抛出
        """
        try:
            logger.info(f"开始生成海报，模板: {template_name}")

            # 1. 如果没有提供内容，使用AI生成
            if not content:
                content = await self._generate_poster_content(**kwargs)

            # 2. 预处理图像
            processed_images = self._process_images(images or [])
            
            if not processed_images:
                raise PosterGenerationError("未提供有效的图像")

            # 3. 获取模板并生成海报
            template = self.template_manager.get_template(template_name)
            
            # 合并样式选项
            generation_options = self._merge_style_options(style_options, kwargs)
            
            # 生成海报
            poster_image = template.generate(
                images=processed_images,
                content=content,
                **generation_options
            )

            if not poster_image:
                raise PosterGenerationError("模板生成海报失败")

            # 4. 保存海报
            poster_path = self.output_manager.save_image(poster_image, "poster")

            # 5. 保存生成配置和内容
            generation_data = {
                "template_name": template_name,
                "content": content,
                "style_options": style_options,
                "generation_options": generation_options,
                "poster_path": poster_path,
                "image_count": len(processed_images),
                "poster_size": poster_image.size,
                "template_config": template.get_config(),
                "metadata": {
                    "model_config": self.task_model_config,
                    "generated_at": self.output_manager.run_id
                }
            }

            self.output_manager.save_json(generation_data, "poster_data")

            # 6. 保存元数据
            metadata = {
                "template_name": template_name,
                "content_word_count": len(content.get("content", "")),
                "model_config": self.task_model_config,
                "poster_config": self.config.poster_generation.dict(),
                "generation_options": generation_options
            }
            self.output_manager.save_metadata(metadata, "poster_generation")

            logger.info(f"海报生成完成，保存路径: {poster_path}")
            return self.output_manager.run_id, generation_data

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

    async def _generate_poster_content(self, **kwargs) -> Dict[str, Any]:
        """使用AI生成海报内容"""
        try:
            topic_info = kwargs.get("topic_info", "旅游景点推荐")
            style = kwargs.get("content_style", "活泼有趣")
            
            content = await self.text_generator.generate_poster_content(
                topic_info=topic_info,
                style=style,
                **kwargs
            )
            
            return content
            
        except Exception as e:
            logger.warning(f"AI生成海报内容失败，使用默认内容: {e}")
            return self._get_default_content()

    def _process_images(self, images: List[Union[str, Image.Image]]) -> List[Image.Image]:
        """预处理图像列表"""
        processed_images = []
        
        for img in images:
            try:
                if isinstance(img, str):
                    # 从路径加载图像
                    img_path = Path(img)
                    if img_path.exists():
                        pil_image = Image.open(img_path)
                        processed_images.append(pil_image.convert("RGB"))
                    else:
                        logger.warning(f"图像文件不存在: {img_path}")
                elif isinstance(img, Image.Image):
                    # 直接使用PIL图像
                    processed_images.append(img.convert("RGB"))
                else:
                    logger.warning(f"不支持的图像类型: {type(img)}")
                    
            except Exception as e:
                logger.error(f"处理图像失败: {e}")
                continue
        
        return processed_images

    def _merge_style_options(
        self, 
        style_options: Optional[Dict[str, Any]], 
        kwargs: Dict[str, Any]
    ) -> Dict[str, Any]:
        """合并样式选项"""
        
        # 从配置获取默认选项
        default_options = {
            "size": self.config.poster_generation.default_size,
            "color_themes": self.config.poster_generation.color_themes,
            "font_configs": self.config.poster_generation.font_configs,
            "glass_effect": self.config.poster_generation.glass_effect,
            "text_effects": self.config.poster_generation.text_effects
        }
        
        # 合并用户提供的选项
        merged_options = default_options.copy()
        if style_options:
            merged_options.update(style_options)
        
        # 合并kwargs中的选项
        poster_related_kwargs = {k: v for k, v in kwargs.items() 
                               if k in ["theme_color", "glass_intensity", "num_variations", "font_size"]}
        merged_options.update(poster_related_kwargs)
        
        return merged_options

    def _get_default_content(self) -> Dict[str, Any]:
        """获取默认海报内容"""
        return {
            "title": "探索美景",
            "content": "发现世界的美好，记录旅途的精彩瞬间。",
            "tags": ["旅游", "美景", "探索"],
            "call_to_action": "立即出发"
        }

    async def generate_poster_batch(
        self,
        content_list: List[Dict[str, Any]],
        template_name: str = "vibrant",
        **kwargs
    ) -> Dict[str, Dict[str, Any]]:
        """
        批量生成海报

        Args:
            content_list: 内容列表
            template_name: 模板名称
            **kwargs: 其他参数

        Returns:
            批次ID->海报数据的字典
        """
        results = {}
        
        for i, content in enumerate(content_list):
            try:
                logger.info(f"批量生成海报 {i+1}/{len(content_list)}")
                
                request_id, poster_data = await self.generate_poster(
                    content=content,
                    template_name=template_name,
                    **kwargs
                )
                
                results[f"poster_{i+1}"] = poster_data
                
            except Exception as e:
                logger.error(f"批量生成第 {i+1} 项失败: {e}")
                results[f"poster_{i+1}"] = {"error": str(e)}
        
        return results

    def get_available_templates(self) -> List[str]:
        """获取可用的模板列表"""
        return self.template_manager.get_available_templates()

    def get_template_info(self, template_name: str) -> Dict[str, Any]:
        """获取模板信息"""
        return self.template_manager.get_template_info(template_name)

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

        Returns:
            测试是否成功
        """
        try:
            # 创建测试图像
            test_image = Image.new("RGB", (400, 300), color="lightblue")
            
            _, poster_data = await self.generate_poster(
                content=self._get_default_content(),
                images=[test_image],
                template_name="vibrant"
            )
            
            return "poster_path" in poster_data
            
        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,
            "available_templates": self.get_available_templates(),
            "default_size": self.config.poster_generation.default_size,
            "color_themes": list(self.config.poster_generation.color_themes.keys()),
            "output_directory": str(self.output_manager.run_output_dir),
            "ai_model_info": self.ai_service.get_model_info(),
            "template_manager_info": self.template_manager.get_manager_info()
        } 