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

"""
Vibrant风格（活力风格）海报模板
"""
from ast import List
import logging
import math
from typing import Dict, Any, Optional, Tuple

import numpy as np
from PIL import Image, ImageDraw, ImageFont, ImageFilter

from .base_template import BaseTemplate
from ..utils import ColorExtractor

logger = logging.getLogger(__name__)


class VibrantTemplate(BaseTemplate):
    """
    活力风格模板，适用于色彩鲜艳、内容丰富的场景，如旅游、美食分享。
    特点是底部有毛玻璃效果的文案区域。
    """
    def __init__(self, size: Tuple[int, int] = (900, 1200)):
        super().__init__(size)
        self.config = {
            'colors': {
                'ocean_deep': [(0, 30, 80), (20, 120, 220)],
                'sunset_warm': [(255, 94, 77), (255, 154, 0)],
                'cool_mint': [(64, 224, 208), (127, 255, 212)],
                'royal_purple': [(75, 0, 130), (138, 43, 226)],
                'forest_green': [(34, 139, 34), (144, 238, 144)],
                'fire_red': [(220, 20, 60), (255, 69, 0)],
                "gray_gradient": [(128, 128, 128), (211, 211, 211)],
                "dark_gray": [(15, 15, 15), (30, 30, 30)]
            },
            'glass_effect': {
                'max_opacity': 240,
                'blur_radius': 22,
                'transition_height': 80,
                'intensity_multiplier': 1.5
            },
        }
        # 设置中文字体路径
        self.chinese_font_path = "/root/TravelContentCreator/assets/font/兰亭粗黑简.TTF"
        
        # 重写text_renderer的字体加载方法以支持中文
        self._patch_text_renderer_for_chinese()

    def _patch_text_renderer_for_chinese(self):
        """重写text_renderer的字体加载方法以支持中文"""
        original_load_font = self.text_renderer._load_default_font
        
        def load_chinese_font(size: int):
            try:
                return ImageFont.truetype(self.chinese_font_path, size)
            except:
                logger.warning(f"无法加载中文字体，使用默认字体")
                return original_load_font(size)
        
        # 替换字体加载方法
        self.text_renderer._load_default_font = load_chinese_font

    def generate(self,
                 images: List,
                 content: Optional[Dict[str, Any]] = None,
                 theme_color: Optional[str] = None,
                 glass_intensity: float = 1.5,
                 num_variations: int = 1,
                 **kwargs) -> Image.Image:
        """
        生成Vibrant风格海报

        Args:
            images (List): 主图
            content (Optional[Dict[str, Any]]): 包含所有文本信息的字典
            theme_color (Optional[str]): 预设颜色主题的名称
            glass_intensity (float): 毛玻璃效果强度
            num_variations (int): 生成海报数量

        Returns:
            Image.Image: 生成的海报图像
        """
        if content is None:
            content = self._get_default_content()

        self.config['glass_effect']['intensity_multiplier'] = glass_intensity

        main_image = images
        logger.info(f"main_image的类型: {np.shape(main_image)}")
        if not main_image:
            logger.error(f"无法加载图片: ")
            return None

        main_image = self.image_processor.resize_image(image=main_image, target_size=self.size)

        estimated_height = self._estimate_content_height(content)
        gradient_start = self._detect_gradient_start_position(main_image, estimated_height)

        canvas = self._create_composite_image(main_image, gradient_start, theme_color)
        canvas = self._render_texts(canvas, content, gradient_start)

        final_image = canvas.resize((1350, 1800), Image.LANCZOS)
        return final_image

    def _get_default_content(self) -> Dict[str, Any]:
        """获取默认的测试内容"""
        return {
            "title": "正佳极地海洋世界",
            "slogan": "都说海洋馆是约会圣地！那锦峰夜场将是绝杀！",
            "price": "199",
            "ticket_type": "夜场票",
            "content_button": "套餐内容",
            "content_items": [
                "正佳极地海洋世界夜场票1张",
                "有效期至2025.06.02",
                "多种动物表演全部免费"
            ],
            "remarks": [
                "工作日可直接入园",
                "周末请提前1天预约"
            ],
            "tag": "#520特惠",
            "pagination": ""
        }

    def _estimate_content_height(self, content: Dict[str, Any]) -> int:
        """预估内容高度"""
        standard_margin = 25
        title_height = 100
        subtitle_height = 80
        button_height = 40
        content_items = content.get("content_items", [])
        content_line_height = 32
        content_list_height = len(content_items) * content_line_height
        price_height = 90
        ticket_height = 60
        remarks = content.get("remarks", [])
        if isinstance(remarks, str):
            remarks = [remarks]
        remarks_height = len(remarks) * 25 + 10
        footer_height = 40
        total_height = (
            20 + title_height + standard_margin + subtitle_height + standard_margin +
            button_height + 15 + content_list_height + price_height + ticket_height +
            remarks_height + footer_height + 30
        )
        return total_height

    def _detect_gradient_start_position(self, image: Image.Image, estimated_height: int) -> int:
        """动态检测渐变起始位置"""
        width, height = image.size
        center_x = width // 2
        gradient_start = None
        for y in range(height // 2, height):
            try:
                pixel = image.getpixel((center_x, y))
                if isinstance(pixel, (tuple, list)) and len(pixel) >= 3:
                    brightness = sum(pixel[:3]) / 3
                    if brightness > 50:
                        gradient_start = max(y - 20, height // 2)
                        break
            except:
                continue
        if gradient_start is None:
            bottom_margin = 60
            gradient_start = max(height - estimated_height - bottom_margin, height // 2)
        return gradient_start

    def _create_composite_image(self, main_image: Image.Image, 
                              gradient_start: int, 
                              theme_color: Optional[str]) -> Image.Image:
        """创建毛玻璃背景和复合图像"""
        if theme_color and theme_color in self.config['colors']:
            top_color, bottom_color = self.config['colors'][theme_color]
        else:
            top_color, bottom_color = self._extract_glass_colors_from_image(main_image, gradient_start)
        
        logger.info(f"使用毛玻璃颜色: 顶部={top_color}, 底部={bottom_color}")
        
        gradient_overlay = self._create_frosted_glass_overlay(top_color, bottom_color, gradient_start)
        
        composite_img = Image.new('RGBA', self.size, (0, 0, 0, 0))
        composite_img.paste(main_image, (0, 0))
        composite_img = Image.alpha_composite(composite_img, gradient_overlay)
        
        return composite_img

    def _create_frosted_glass_overlay(self, top_color: Tuple[int, int, int], 
                                    bottom_color: Tuple[int, int, int], 
                                    gradient_start: int) -> Image.Image:
        """创建高级毛玻璃效果覆盖层"""
        overlay = Image.new('RGBA', self.size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(overlay)

        gradient_height = self.height - gradient_start
        glass_config = self.config['glass_effect']
        intensity = glass_config['intensity_multiplier']

        enhanced_opacity = min(255, int(glass_config['max_opacity'] * intensity))
        enhanced_blur = int(glass_config['blur_radius'] * intensity)

        def enhance_color(color, multiplier):
            factor = min(1.5, 1.0 + (multiplier - 1.0) * 0.3)
            return tuple(min(255, max(0, int(c * factor))) for c in color)

        top_c = enhance_color(top_color, intensity)
        bottom_c = enhance_color(bottom_color, intensity)
        top_c_arr = np.array(top_c)
        bottom_c_arr = np.array(bottom_c)

        for y in range(gradient_start, self.height):
            ratio = (y - gradient_start) / gradient_height if gradient_height > 0 else 0
            smooth_ratio = 0.5 - 0.5 * math.cos(ratio * math.pi)
            color = (1 - smooth_ratio) * top_c_arr + smooth_ratio * bottom_c_arr
            alpha_smooth = ratio ** (1.1 / intensity)
            alpha = int(enhanced_opacity * (0.02 + 0.98 * alpha_smooth))

            if (y - gradient_start) < glass_config['transition_height']:
                transition_ratio = (y - gradient_start) / glass_config['transition_height']
                alpha = int(alpha * (0.5 - 0.5 * math.cos(transition_ratio * math.pi)))

            color_tuple = tuple(int(c) for c in color) + (alpha,)
            draw.line([(0, y), (self.width, y)], fill=color_tuple)
        
        return overlay.filter(ImageFilter.GaussianBlur(radius=enhanced_blur))

    def _extract_glass_colors_from_image(self, image: Image.Image, gradient_start: int) -> tuple:
        """从图片中提取用于毛玻璃背景的颜色"""
        if image.mode != 'RGB':
            image = image.convert('RGB')
        
        width, height = image.size
        top_samples, bottom_samples = [], []

        top_y = min(gradient_start + 20, height - 1)
        for x in range(0, width, 20):
            if sum(pixel := image.getpixel((x, top_y))) > 30:
                top_samples.append(pixel)
        
        bottom_y = min(height - 50, height - 1)
        for x in range(0, width, 20):
            if sum(pixel := image.getpixel((x, bottom_y))) > 30:
                bottom_samples.append(pixel)

        top_color = tuple(max(0, int(c * 0.1)) for c in np.mean(top_samples, axis=0)) if top_samples else (0, 5, 15)
        bottom_color = tuple(max(0, int(c * 0.2)) for c in np.mean(bottom_samples, axis=0)) if bottom_samples else (0, 25, 50)
        
        return top_color, bottom_color

    def _calculate_optimal_font_size_enhanced(self, text: str, target_width: int, 
                                            max_size: int = 120, min_size: int = 10) -> Tuple[int, int]:
        """
        计算文本的最佳字体大小，使其宽度接近目标宽度（增强版本，与demo一致）
        
        返回:
        (字体大小, 实际文本宽度)
        """
        # 二分查找最佳字体大小
        low = min_size
        high = max_size
        best_size = min_size
        best_width = 0
        tolerance = 0.08  # 容差值，使文本宽度更接近目标值
        
        # 首先尝试最大字体大小
        try:
            font = self.text_renderer._load_default_font(max_size)
            max_width, _ = self.text_renderer.get_text_size(text, font)
        except:
            max_width = target_width * 2  # 如果出错，设置一个大值
        
        # 如果最大字体大小下的宽度仍小于目标宽度的108%，直接使用最大字体
        if max_width < target_width * (1 + tolerance):
            best_size = max_size
            best_width = max_width
        else:
            # 记录最接近目标宽度的字体大小
            closest_size = min_size
            closest_diff = target_width
            
            while low <= high:
                mid = (low + high) // 2
                try:
                    font = self.text_renderer._load_default_font(mid)
                    width, _ = self.text_renderer.get_text_size(text, font)
                except:
                    width = target_width * 2  # 如果出错，设置一个大值
                
                # 计算与目标宽度的差距
                diff = abs(width - target_width)
                
                # 更新最接近的字体大小
                if diff < closest_diff:
                    closest_diff = diff
                    closest_size = mid
                
                # 如果宽度在目标宽度的允许范围内，认为找到了最佳匹配
                if target_width * (1 - tolerance) <= width <= target_width * (1 + tolerance):
                    best_size = mid
                    best_width = width
                    break
                    
                # 如果当前宽度小于目标宽度，尝试更大的字体
                if width < target_width:
                    if width > best_width:
                        best_width = width
                        best_size = mid
                    low = mid + 1
                else:
                    # 如果当前宽度大于目标宽度，尝试更小的字体
                    high = mid - 1
            
            # 如果没有找到在容差范围内的字体大小，使用最接近的字体大小
            if best_width == 0:
                best_size = closest_size
        
        # 确保返回的宽度是使用最终字体计算的实际宽度
        try:
            best_font = self.text_renderer._load_default_font(best_size)
            final_width, _ = self.text_renderer.get_text_size(text, best_font)
        except:
            final_width = best_width
        
        logger.info(f"文本'{text[:min(10, len(text))]}...'的最佳字体大小: {best_size}，目标宽度: {target_width}，实际宽度: {final_width}，差距: {abs(final_width-target_width)}")
        
        return best_size, final_width

    def _render_texts(self, canvas: Image.Image, content: Dict[str, Any], gradient_start: int) -> Image.Image:
        """渲染所有文本元素，采用双栏布局"""
        draw = ImageDraw.Draw(canvas)
        width, height = canvas.size
        center_x = width // 2

        left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
        
        footer_y = height - 30
        self._render_footer(draw, content, footer_y, left_margin, right_margin)

        title_y = gradient_start + 40
        current_y = self._render_title_subtitle(draw, content, title_y, center_x, left_margin, right_margin)

        content_area_width = right_margin - left_margin
        left_column_width = int(content_area_width * 0.5)
        right_column_x = left_margin + left_column_width

        content_start_y = current_y + 30
        self._render_left_column(draw, content, content_start_y, left_margin, left_column_width, height)
        self._render_right_column(draw, content, content_start_y, right_column_x, right_margin)

        return canvas

    def _calculate_content_margins(self, content: Dict[str, Any], width: int, center_x: int) -> Tuple[int, int]:
        """计算内容区域的左右边距（增强版本，与demo一致）"""
        # 计算标题位置
        title_text = content.get("title", "")
        title_target_width = int(width * 0.95)
        title_size, title_width = self._calculate_optimal_font_size_enhanced(
            title_text, title_target_width, min_size=40, max_size=130
        )
        title_x = center_x - title_width // 2
        
        # 计算副标题位置
        slogan_text = content.get("slogan", "")
        subtitle_target_width = int(width * 0.9)
        subtitle_size, subtitle_width = self._calculate_optimal_font_size_enhanced(
            slogan_text, subtitle_target_width, max_size=50, min_size=20
        )
        subtitle_x = center_x - subtitle_width // 2
        
        # 计算内容区域边距 - 减小额外的边距，让内容区域更宽
        padding = 20  # 从30减小到20
        content_left_margin = min(title_x, subtitle_x) - padding
        content_right_margin = max(title_x + title_width, subtitle_x + subtitle_width) + padding
        
        # 确保边距不超出合理范围，但允许更宽的内容区域
        content_left_margin = max(40, content_left_margin)
        content_right_margin = min(width - 40, content_right_margin)
        
        # 如果内容区域太窄，强制使用更宽的区域
        min_content_width = int(width * 0.75)  # 至少使用75%的宽度
        current_width = content_right_margin - content_left_margin
        if current_width < min_content_width:
            extra_width = min_content_width - current_width
            content_left_margin = max(30, content_left_margin - extra_width // 2)
            content_right_margin = min(width - 30, content_right_margin + extra_width // 2)
        
        return content_left_margin, content_right_margin

    def _render_footer(self, draw: ImageDraw.Draw, content: Dict[str, Any], y: int, left: int, right: int):
        """渲染页脚文本"""
        font = self.text_renderer._load_default_font(18)
        if tag := content.get("tag"):
            draw.text((left, y), tag, font=font, fill=(255, 255, 255))
        if pagination := content.get("pagination"):
            width, _ = self.text_renderer.get_text_size(pagination, font)
            draw.text((right - width, y), pagination, font=font, fill=(255, 255, 255))

    def _render_title_subtitle(self, draw: ImageDraw.Draw, content: Dict[str, Any], y: int, center_x: int, left: int, right: int) -> int:
        """渲染标题和副标题（增强版本，与demo一致）"""
        # 标题
        title_text = content.get("title", "默认标题")
        title_target_width = int((right - left) * 0.98)
        title_size, title_actual_width = self._calculate_optimal_font_size_enhanced(
            title_text, title_target_width, max_size=140, min_size=40
        )
        title_font = self.text_renderer._load_default_font(title_size)
        
        text_w, text_h = self.text_renderer.get_text_size(title_text, title_font)
        title_x = center_x - text_w // 2
        
        self.text_renderer.draw_text_with_outline(draw, (title_x, y), title_text, title_font, text_color=(255, 255, 255, 255), outline_color=(0, 30, 80, 200), outline_width=4)
        
        # 副标题 (slogan)
        subtitle_text = content.get("slogan", "")
        subtitle_target_width = int((right - left) * 0.95)
        subtitle_size, subtitle_actual_width = self._calculate_optimal_font_size_enhanced(
            subtitle_text, subtitle_target_width, max_size=75, min_size=20
        )
        subtitle_font = self.text_renderer._load_default_font(subtitle_size)
        
        sub_text_w, sub_text_h = self.text_renderer.get_text_size(subtitle_text, subtitle_font)
        subtitle_x = center_x - sub_text_w // 2
        
        title_spacing = 30
        
        # 在标题下方添加装饰线
        line_y = y + text_h + 5
        line_start_x = title_x - text_w * 0.025
        line_end_x = title_x + text_w * 1.025
        draw.line([(line_start_x, line_y), (line_end_x, line_y)], fill=(215, 215, 215, 80), width=3)

        subtitle_y = y + text_h + title_spacing
        
        self.text_renderer.draw_text_with_shadow(draw, (subtitle_x, subtitle_y), subtitle_text, subtitle_font, text_color=(255, 255, 255, 255), shadow_color=(0, 0, 0, 180), shadow_offset=(2, 2))
        
        return subtitle_y + sub_text_h

    def _render_left_column(self, draw: ImageDraw.Draw, content: Dict[str, Any], y: int, x: int, width: int, canvas_height: int):
        """渲染左栏内容：按钮和项目列表"""
        button_font = self.text_renderer._load_default_font(30)
        button_text = content.get("content_button", "套餐内容")
        button_width, _ = self.text_renderer.get_text_size(button_text, button_font)
        button_width += 40
        button_height = 50
        self.text_renderer.draw_rounded_rectangle(draw=draw, position=(x, y), size=(button_width, button_height), radius=20, fill_color=(0, 140, 210, 180), outline_color=(255, 255, 255, 255), outline_width=1)
        draw.text((x + 20, y + (button_height - 30) // 2), button_text, font=button_font, fill=(255, 255, 255))

        items = content.get("content_items", [])
        if not items: return
        
        font = self.text_renderer._load_default_font(28)
        list_y = y + button_height + 20
        available_h = canvas_height - 30 - (len(content.get("remarks", [])) * 25 + 10) - list_y - 20
        total_items_h = len(items) * 36
        extra_space_per_item = max(0, min(17, (available_h - total_items_h) / max(1, len(items) - 1)))
        line_spacing = 8 + extra_space_per_item
        
        for i, item in enumerate(items):
            item_y = list_y + i * (28 + line_spacing)
            draw.text((x, item_y), " " + item, font=font, fill=(255, 255, 255))

    def _render_right_column(self, draw: ImageDraw.Draw, content: Dict[str, Any], y: int, x: int, right_margin: int):
        """渲染右栏内容：价格、票种和备注（增强版本，与demo一致）"""
        price_text = str(content.get('price', ''))  # 确保价格是字符串类型
        price_target_width = int((right_margin - x) * 0.7)
        price_size, price_actual_width = self._calculate_optimal_font_size_enhanced(
            price_text, price_target_width, max_size=120, min_size=40
        )
        
        price_font = self.text_renderer._load_default_font(price_size)
        suffix_font = self.text_renderer._load_default_font(int(price_size * 0.3))
        _, price_height = self.text_renderer.get_text_size(price_text, price_font)
        suffix_width, suffix_height = self.text_renderer.get_text_size("CNY起", suffix_font)
        
        price_x = right_margin - price_actual_width - suffix_width
        self.text_renderer.draw_text_with_shadow(draw, (price_x, y), price_text, price_font)
        
        suffix_y = y + price_height - suffix_height
        draw.text((price_x + price_actual_width, suffix_y), "CNY起", font=suffix_font, fill=(255, 255, 255))
        
        underline_y = y + price_height + 18
        draw.line([(price_x - 10, underline_y), (right_margin, underline_y)], fill=(255, 255, 255, 80), width=2)
        
        ticket_text = content.get("ticket_type", "")
        ticket_target_width = int((right_margin - x) * 0.7)
        ticket_size, ticket_actual_width = self._calculate_optimal_font_size_enhanced(
            ticket_text, ticket_target_width, max_size=60, min_size=30
        )
        ticket_font = self.text_renderer._load_default_font(ticket_size)
        ticket_x = right_margin - ticket_actual_width
        ticket_y = y + price_height + 35
        self.text_renderer.draw_text_with_shadow(draw, (ticket_x, ticket_y), ticket_text, ticket_font)
        _, ticket_height = self.text_renderer.get_text_size(ticket_text, ticket_font)

        remarks = content.get("remarks", [])
        if remarks:
            remarks_font = self.text_renderer._load_default_font(16)
            remarks_y = ticket_y + ticket_height + 30
            for i, remark in enumerate(remarks):
                remark_width, _ = self.text_renderer.get_text_size(remark, remarks_font)
                draw.text((right_margin - remark_width, remarks_y + i * 21), remark, font=remarks_font, fill=(255, 255, 255, 200)) 

    def generate_layered_psd(self,
                           images,
                           content: Optional[Dict[str, Any]] = None,
                           theme_color: Optional[str] = None,
                           glass_intensity: float = 1.5,
                           output_path: str = "layered_poster.psd",
                           **kwargs) -> str:
        """
        生成分层的PSD文件，方便后续修改
        
        Args:
            images: 主图
            content: 包含所有文本信息的字典
            theme_color: 预设颜色主题的名称
            glass_intensity: 毛玻璃效果强度
            output_path: PSD文件输出路径
            
        Returns:
            str: 生成的PSD文件路径
        """
        try:
            from psd_tools import PSDImage
            from psd_tools.api.layers import PixelLayer
        except ImportError:
            logger.error("需要安装psd-tools库: pip install psd-tools")
            return None
            
        logger.info("开始生成分层PSD文件...")
        
        if content is None:
            content = self._get_default_content()

        self.config['glass_effect']['intensity_multiplier'] = glass_intensity

        main_image = images
        if not main_image:
            logger.error("无法加载图片")
            return None

        # 参考原始合成模式的PSD版本实现
        main_image = self.image_processor.resize_image(image=main_image, target_size=self.size)
        estimated_height = self._estimate_content_height(content)
        gradient_start = self._detect_gradient_start_position(main_image, estimated_height)

        # === 第一步：创建与常规模式完全相同的最终结果作为Reference ===
        canvas = self._create_composite_image(main_image, gradient_start, theme_color)
        canvas = self._render_texts(canvas, content, gradient_start)
        final_canvas = canvas.resize((1350, 1800), Image.LANCZOS)
        
        # === 第二步：为PSD创建可编辑的图层版本 ===
        final_size = (1350, 1800)
        psd = PSDImage.new("RGBA", final_size, color=(0, 0, 0, 0))
        logger.info(f"创建PSD文档，尺寸: {final_size}")

        # 图层1：完美一致的参考图层
        composite_layer = PixelLayer.frompil(final_canvas, psd, "Perfect Reference")
        psd.append(composite_layer)
        logger.info("✓ 添加完美参考图层")
        
        # === 第三步：提供丰富的可编辑图层 ===
        
        # 图层2：纯背景图层（无任何效果）
        background_only = main_image.resize(final_size, Image.LANCZOS)
        bg_layer = PixelLayer.frompil(background_only, psd, "Background Image")
        psd.append(bg_layer)
        logger.info("✓ 添加纯背景图层")
        
        # 图层3：毛玻璃效果图层
        glass_overlay = self._create_glass_overlay_layer(main_image, gradient_start, theme_color)
        if glass_overlay:
            glass_scaled = glass_overlay.resize(final_size, Image.LANCZOS)
            glass_layer = PixelLayer.frompil(glass_scaled, psd, "Glass Overlay")
            psd.append(glass_layer)
            logger.info("✓ 添加毛玻璃效果图层")
        
        # 图层4-9：分离的文字图层
        detailed_text_layers = self._create_detailed_text_layers(content, gradient_start, self.size)
        for layer_name, layer_image in detailed_text_layers.items():
            if layer_image:
                text_scaled = layer_image.resize(final_size, Image.LANCZOS)
                text_layer = PixelLayer.frompil(text_scaled, psd, layer_name)
                psd.append(text_layer)
                logger.info(f"✓ 添加文字图层: {layer_name}")
        
        # 图层10：整体文字图层（备用）
        text_only_canvas = self._create_text_only_layer(content, gradient_start, self.size)
        if text_only_canvas:
            text_only_scaled = text_only_canvas.resize(final_size, Image.LANCZOS)
            all_text_layer = PixelLayer.frompil(text_only_scaled, psd, "All Text (Backup)")
            psd.append(all_text_layer)
            logger.info("✓ 添加整体文字备用图层")
        
        logger.info(f"PSD包含{len(list(psd))}个图层：1个参考层+{len(list(psd))-1}个编辑层")

        # 保存PSD文件
        psd.save(output_path)
        logger.info(f"✓ PSD文件已保存: {output_path} (尺寸: {psd.size})")
        
        return output_path

    def _create_glass_overlay_layer(self, main_image: Image.Image, gradient_start: int, theme_color: Optional[str]) -> Optional[Image.Image]:
        """创建毛玻璃效果的独立图层"""
        try:
            if theme_color and theme_color in self.config['colors']:
                top_color, bottom_color = self.config['colors'][theme_color]
            else:
                top_color, bottom_color = self._extract_glass_colors_from_image(main_image, gradient_start)
            
            # 创建透明背景的毛玻璃层
            overlay = self._create_frosted_glass_overlay(top_color, bottom_color, gradient_start)
            return overlay
        except Exception as e:
            logger.error(f"创建毛玻璃层失败: {e}")
            return None



    def _create_text_layers(self, content: Dict[str, Any], gradient_start: int) -> Dict[str, Optional[Image.Image]]:
        """创建各个文字图层"""
        layers = {}
        
        try:
            # 创建透明画布
            canvas_size = self.size
            
            # 计算布局参数
            width, height = canvas_size
            center_x = width // 2
            left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
            
            # 1. 标题层
            layers["Title Text"] = self._create_title_layer(content, gradient_start, center_x, left_margin, right_margin, canvas_size)
            
            # 2. 副标题层  
            layers["Subtitle Text"] = self._create_subtitle_layer(content, gradient_start, center_x, left_margin, right_margin, canvas_size)
            
            # 3. 装饰线层
            layers["Decorations"] = self._create_decoration_layer(content, gradient_start, center_x, left_margin, right_margin, canvas_size)
            
            # 4. 左栏内容层
            title_y = gradient_start + 40
            subtitle_height = 80 + 30  # 预估副标题高度
            content_start_y = title_y + subtitle_height + 30
            content_area_width = right_margin - left_margin
            left_column_width = int(content_area_width * 0.5)
            
            layers["Left Content"] = self._create_left_column_layer(content, content_start_y, left_margin, left_column_width, canvas_size)
            
            # 5. 右栏内容层
            right_column_x = left_margin + left_column_width
            layers["Right Content"] = self._create_right_column_layer(content, content_start_y, right_column_x, right_margin, canvas_size)
            
            # 6. 页脚层
            footer_y = height - 30
            layers["Footer Info"] = self._create_footer_layer(content, footer_y, left_margin, right_margin, canvas_size)
            
        except Exception as e:
            logger.error(f"创建文字图层失败: {e}")
            
        return layers

    def _create_text_only_layer(self, content: Dict[str, Any], gradient_start: int, canvas_size: tuple) -> Optional[Image.Image]:
        """创建纯文字图层（透明背景），模拟_render_texts的渲染逻辑"""
        try:
            # 创建透明画布
            text_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(text_canvas)
            
            width, height = canvas_size
            center_x = width // 2

            # 使用与原始方法相同的布局计算
            left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
            
            # 页脚
            footer_y = height - 30
            self._render_footer(draw, content, footer_y, left_margin, right_margin)

            # 标题和副标题
            title_y = gradient_start + 40
            current_y = self._render_title_subtitle(draw, content, title_y, center_x, left_margin, right_margin)

            # 左右栏内容
            content_area_width = right_margin - left_margin
            left_column_width = int(content_area_width * 0.5)
            right_column_x = left_margin + left_column_width

            content_start_y = current_y + 30
            self._render_left_column(draw, content, content_start_y, left_margin, left_column_width, height)
            self._render_right_column(draw, content, content_start_y, right_column_x, right_margin)

            return text_canvas
        except Exception as e:
            logger.error(f"创建纯文字图层失败: {e}")
            return None

    def _create_text_only_layer(self, content: Dict[str, Any], gradient_start: int, canvas_size: tuple) -> Optional[Image.Image]:
        """创建纯文字图层（透明背景），模拟_render_texts的渲染逻辑"""
        try:
            # 创建透明画布
            text_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(text_canvas)
            
            width, height = canvas_size
            center_x = width // 2

            # 使用与原始方法相同的布局计算
            left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
            
            # 页脚
            footer_y = height - 30
            self._render_footer(draw, content, footer_y, left_margin, right_margin)

            # 标题和副标题
            title_y = gradient_start + 40
            current_y = self._render_title_subtitle(draw, content, title_y, center_x, left_margin, right_margin)

            # 左右栏内容
            content_area_width = right_margin - left_margin
            left_column_width = int(content_area_width * 0.5)
            right_column_x = left_margin + left_column_width

            content_start_y = current_y + 30
            self._render_left_column(draw, content, content_start_y, left_margin, left_column_width, height)
            self._render_right_column(draw, content, content_start_y, right_column_x, right_margin)

            return text_canvas
        except Exception as e:
            logger.error(f"创建纯文字图层失败: {e}")
            return None

    def _create_detailed_text_layers(self, content: Dict[str, Any], gradient_start: int, canvas_size: tuple) -> Dict[str, Optional[Image.Image]]:
        """创建详细的分离文字图层，每个文字元素独立可编辑"""
        layers = {}
        
        try:
            width, height = canvas_size
            center_x = width // 2
            left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
            
            # 1. 标题图层
            title_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            title_draw = ImageDraw.Draw(title_canvas)
            title_y = gradient_start + 40
            
            title_text = content.get("title", "默认标题")
            title_target_width = int((right_margin - left_margin) * 0.98)
            title_size, title_actual_width = self._calculate_optimal_font_size_enhanced(
                title_text, title_target_width, max_size=140, min_size=40
            )
            try:
                title_font = ImageFont.truetype(self.chinese_font_path, title_size)
            except:
                title_font = self.text_renderer._load_default_font(title_size)
            text_w, text_h = self.text_renderer.get_text_size(title_text, title_font)
            title_x = center_x - text_w // 2
            
            self.text_renderer.draw_text_with_outline(title_draw, (title_x, title_y), title_text, title_font, 
                                                    text_color=(255, 255, 255, 255), outline_color=(0, 30, 80, 200), outline_width=4)
            layers["Title Text"] = title_canvas
            
            # 2. 副标题图层
            subtitle_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            subtitle_draw = ImageDraw.Draw(subtitle_canvas)
            
            subtitle_text = content.get("slogan", "")
            if subtitle_text:
                subtitle_target_width = int((right_margin - left_margin) * 0.95)
                subtitle_size, subtitle_actual_width = self._calculate_optimal_font_size_enhanced(
                    subtitle_text, subtitle_target_width, max_size=75, min_size=20
                )
                try:
                    subtitle_font = ImageFont.truetype(self.chinese_font_path, subtitle_size)
                except:
                    subtitle_font = self.text_renderer._load_default_font(subtitle_size)
                sub_text_w, sub_text_h = self.text_renderer.get_text_size(subtitle_text, subtitle_font)
                subtitle_x = center_x - sub_text_w // 2
                subtitle_y = title_y + text_h + 30
                
                self.text_renderer.draw_text_with_shadow(subtitle_draw, (subtitle_x, subtitle_y), subtitle_text, subtitle_font,
                                                       text_color=(255, 255, 255, 255), shadow_color=(0, 0, 0, 180), shadow_offset=(2, 2))
                layers["Subtitle Text"] = subtitle_canvas
            
            # 3. 页脚图层
            footer_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            footer_draw = ImageDraw.Draw(footer_canvas)
            
            footer_y = height - 30
            try:
                footer_font = ImageFont.truetype(self.chinese_font_path, 18)
            except:
                footer_font = self.text_renderer._load_default_font(18)
            
            if tag := content.get("tag"):
                footer_draw.text((left_margin, footer_y), tag, font=footer_font, fill=(255, 255, 255))
            if pagination := content.get("pagination"):
                width_pg, _ = self.text_renderer.get_text_size(pagination, footer_font)
                footer_draw.text((right_margin - width_pg, footer_y), pagination, font=footer_font, fill=(255, 255, 255))
            
            layers["Footer"] = footer_canvas
            
        except Exception as e:
            logger.error(f"创建详细文字图层失败: {e}")
            
        return {k: v for k, v in layers.items() if v is not None}

    def _draw_text_with_outline_simple(self, draw: ImageDraw.Draw, position: Tuple[int, int], 
                                     text: str, font: ImageFont.FreeTypeFont,
                                     text_color: Tuple[int, int, int, int] = (255, 255, 255, 255),
                                     outline_color: Tuple[int, int, int, int] = (0, 0, 0, 255),
                                     outline_width: int = 2):
        """简单的文本描边绘制方法"""
        x, y = position
        
        # 绘制描边
        for dx in range(-outline_width, outline_width + 1):
            for dy in range(-outline_width, outline_width + 1):
                if dx == 0 and dy == 0:
                    continue
                draw.text((x + dx, y + dy), text, font=font, fill=outline_color)
        
        # 绘制主文本
        draw.text((x, y), text, font=font, fill=text_color)

    def _draw_text_with_shadow_simple(self, draw: ImageDraw.Draw, position: Tuple[int, int],
                                    text: str, font: ImageFont.FreeTypeFont,
                                    text_color: Tuple[int, int, int, int] = (255, 255, 255, 255),
                                    shadow_color: Tuple[int, int, int, int] = (0, 0, 0, 128),
                                    shadow_offset: Tuple[int, int] = (2, 2)):
        """简单的文本阴影绘制方法"""
        x, y = position
        shadow_x, shadow_y = shadow_offset
        
        # 绘制阴影
        draw.text((x + shadow_x, y + shadow_y), text, font=font, fill=shadow_color)
        
        # 绘制主文本
        draw.text((x, y), text, font=font, fill=text_color)

    def _create_title_layer(self, content: Dict[str, Any], gradient_start: int, center_x: int, left_margin: int, right_margin: int, canvas_size: Tuple[int, int]) -> Optional[Image.Image]:
        """创建标题图层"""
        try:
            canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(canvas)
            
            title_text = content.get("title", "默认标题")
            title_target_width = int((right_margin - left_margin) * 0.98)
            
            # 使用指定的中文字体
            title_size, title_actual_width = self._calculate_optimal_font_size_enhanced(
                title_text, title_target_width, max_size=140, min_size=40
            )
            
            try:
                title_font = ImageFont.truetype(self.chinese_font_path, title_size)
            except:
                title_font = self.text_renderer._load_default_font(title_size)
            
            # 重新计算实际尺寸
            bbox = title_font.getbbox(title_text)
            text_w = bbox[2] - bbox[0]
            text_h = bbox[3] - bbox[1]
            title_x = center_x - text_w // 2
            title_y = gradient_start + 40
            
            # 绘制带描边的标题
            self._draw_text_with_outline_simple(
                draw, (title_x, title_y), title_text, title_font, 
                text_color=(255, 255, 255, 255), 
                outline_color=(0, 30, 80, 200), 
                outline_width=4
            )
            
            return canvas
        except Exception as e:
            logger.error(f"创建标题层失败: {e}")
            import traceback
            traceback.print_exc()
            return None

    def _create_subtitle_layer(self, content: Dict[str, Any], gradient_start: int, center_x: int, left_margin: int, right_margin: int, canvas_size: Tuple[int, int]) -> Optional[Image.Image]:
        """创建副标题图层"""
        try:
            canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(canvas)
            
            subtitle_text = content.get("slogan", "")
            if not subtitle_text:
                return None
                
            subtitle_target_width = int((right_margin - left_margin) * 0.95)
            subtitle_size, subtitle_actual_width = self._calculate_optimal_font_size_enhanced(
                subtitle_text, subtitle_target_width, max_size=75, min_size=20
            )
            
            # 使用指定的中文字体
            try:
                subtitle_font = ImageFont.truetype(self.chinese_font_path, subtitle_size)
            except:
                subtitle_font = self.text_renderer._load_default_font(subtitle_size)
            
            bbox = subtitle_font.getbbox(subtitle_text)
            sub_text_w = bbox[2] - bbox[0]
            sub_text_h = bbox[3] - bbox[1]
            subtitle_x = center_x - sub_text_w // 2
            subtitle_y = gradient_start + 40 + 100 + 30  # title_y + title_height + spacing
            
            # 绘制带阴影的副标题
            self._draw_text_with_shadow_simple(
                draw, (subtitle_x, subtitle_y), subtitle_text, subtitle_font, 
                text_color=(255, 255, 255, 255), 
                shadow_color=(0, 0, 0, 180), 
                shadow_offset=(2, 2)
            )
            
            return canvas
        except Exception as e:
            logger.error(f"创建副标题层失败: {e}")
            import traceback
            traceback.print_exc()
            return None

    def _create_decoration_layer(self, content: Dict[str, Any], gradient_start: int, center_x: int, left_margin: int, right_margin: int, canvas_size: Tuple[int, int]) -> Optional[Image.Image]:
        """创建装饰元素图层"""
        try:
            canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(canvas)
            
            # 获取标题信息用于装饰线定位
            title_text = content.get("title", "默认标题")
            title_target_width = int((right_margin - left_margin) * 0.98)
            title_size, title_actual_width = self._calculate_optimal_font_size_enhanced(
                title_text, title_target_width, max_size=140, min_size=40
            )
            
            # 使用中文字体计算标题尺寸
            try:
                title_font = ImageFont.truetype(self.chinese_font_path, title_size)
            except:
                title_font = self.text_renderer._load_default_font(title_size)
                
            bbox = title_font.getbbox(title_text)
            text_w = bbox[2] - bbox[0]
            text_h = bbox[3] - bbox[1]
            title_x = center_x - text_w // 2
            title_y = gradient_start + 40
            
            # 在标题下方添加装饰线
            line_y = title_y + text_h + 5
            line_start_x = title_x - text_w * 0.025
            line_end_x = title_x + text_w * 1.025
            draw.line([(line_start_x, line_y), (line_end_x, line_y)], fill=(215, 215, 215, 80), width=3)
            
            return canvas
        except Exception as e:
            logger.error(f"创建装饰层失败: {e}")
            import traceback
            traceback.print_exc()
            return None

    def _create_left_column_layer(self, content: Dict[str, Any], y: int, x: int, width: int, canvas_size: Tuple[int, int]) -> Optional[Image.Image]:
        """创建左栏内容图层"""
        try:
            canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(canvas)
            
            # 使用中文字体
            
            # 按钮
            try:
                button_font = ImageFont.truetype(self.chinese_font_path, 30)
            except:
                button_font = self.text_renderer._load_default_font(30)
                
            button_text = content.get("content_button", "套餐内容")
            bbox = button_font.getbbox(button_text)
            button_text_width = bbox[2] - bbox[0]
            button_width = button_text_width + 40
            button_height = 50
            
            # 绘制简单的矩形按钮
            draw.rounded_rectangle([x, y, x + button_width, y + button_height], 
                                 radius=20, fill=(0, 140, 210, 180), 
                                 outline=(255, 255, 255, 255), width=1)
            draw.text((x + 20, y + (button_height - 30) // 2), button_text, font=button_font, fill=(255, 255, 255))

            # 项目列表
            items = content.get("content_items", [])
            if items:
                try:
                    list_font = ImageFont.truetype(self.chinese_font_path, 28)
                except:
                    list_font = self.text_renderer._load_default_font(28)
                    
                list_y = y + button_height + 20
                line_spacing = 36
                
                for i, item in enumerate(items):
                    item_y = list_y + i * line_spacing
                    draw.text((x, item_y), "• " + item, font=list_font, fill=(255, 255, 255))
            
            return canvas
        except Exception as e:
            logger.error(f"创建左栏内容层失败: {e}")
            import traceback
            traceback.print_exc()
            return None

    def _create_right_column_layer(self, content: Dict[str, Any], y: int, x: int, right_margin: int, canvas_size: Tuple[int, int]) -> Optional[Image.Image]:
        """创建右栏内容图层"""
        try:
            canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(canvas)
            
            # 使用中文字体
            
            # 价格
            price_text = str(content.get('price', ''))  # 确保价格是字符串类型
            if price_text:
                price_target_width = int((right_margin - x) * 0.7)
                price_size, price_actual_width = self._calculate_optimal_font_size_enhanced(
                    price_text, price_target_width, max_size=120, min_size=40
                )
                
                try:
                    price_font = ImageFont.truetype(self.chinese_font_path, price_size)
                    suffix_font = ImageFont.truetype(self.chinese_font_path, int(price_size * 0.3))
                except:
                    price_font = self.text_renderer._load_default_font(price_size)
                    suffix_font = self.text_renderer._load_default_font(int(price_size * 0.3))
                
                price_bbox = price_font.getbbox(price_text)
                price_height = price_bbox[3] - price_bbox[1]
                suffix_bbox = suffix_font.getbbox("CNY起")
                suffix_width = suffix_bbox[2] - suffix_bbox[0]
                suffix_height = suffix_bbox[3] - suffix_bbox[1]
                
                price_x = right_margin - price_actual_width - suffix_width
                self._draw_text_with_shadow_simple(draw, (price_x, y), price_text, price_font)
                
                suffix_y = y + price_height - suffix_height
                draw.text((price_x + price_actual_width, suffix_y), "CNY起", font=suffix_font, fill=(255, 255, 255))
                
                # 下划线
                underline_y = y + price_height + 18
                draw.line([(price_x - 10, underline_y), (right_margin, underline_y)], fill=(255, 255, 255, 80), width=2)
                
                # 票种
                ticket_text = content.get("ticket_type", "")
                if ticket_text:
                    ticket_target_width = int((right_margin - x) * 0.7)
                    ticket_size, ticket_actual_width = self._calculate_optimal_font_size_enhanced(
                        ticket_text, ticket_target_width, max_size=60, min_size=30
                    )
                    
                    try:
                        ticket_font = ImageFont.truetype(self.chinese_font_path, ticket_size)
                    except:
                        ticket_font = self.text_renderer._load_default_font(ticket_size)
                        
                    ticket_x = right_margin - ticket_actual_width
                    ticket_y = y + price_height + 35
                    self._draw_text_with_shadow_simple(draw, (ticket_x, ticket_y), ticket_text, ticket_font)
                    
                    ticket_bbox = ticket_font.getbbox(ticket_text)
                    ticket_height = ticket_bbox[3] - ticket_bbox[1]

                    # 备注
                    remarks = content.get("remarks", [])
                    if remarks:
                        try:
                            remarks_font = ImageFont.truetype(self.chinese_font_path, 16)
                        except:
                            remarks_font = self.text_renderer._load_default_font(16)
                            
                        remarks_y = ticket_y + ticket_height + 30
                        for i, remark in enumerate(remarks):
                            remark_bbox = remarks_font.getbbox(remark)
                            remark_width = remark_bbox[2] - remark_bbox[0]
                            draw.text((right_margin - remark_width, remarks_y + i * 21), remark, font=remarks_font, fill=(255, 255, 255, 200))
            
            return canvas
        except Exception as e:
            logger.error(f"创建右栏内容层失败: {e}")
            import traceback
            traceback.print_exc()
            return None

    def _create_footer_layer(self, content: Dict[str, Any], footer_y: int, left_margin: int, right_margin: int, canvas_size: Tuple[int, int]) -> Optional[Image.Image]:
        """创建页脚图层"""
        try:
            canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(canvas)
            
            # 使用中文字体
            try:
                font = ImageFont.truetype(self.chinese_font_path, 18)
            except:
                font = self.text_renderer._load_default_font(18)
            
            # 标签（左下角）
            tag_text = content.get("tag", "")
            if tag_text:
                draw.text((left_margin, footer_y), tag_text, font=font, fill=(255, 255, 255))
            
            # 分页信息（右下角）
            pagination_text = content.get("pagination", "")
            if pagination_text:
                pagination_bbox = font.getbbox(pagination_text)
                pagination_width = pagination_bbox[2] - pagination_bbox[0]
                draw.text((right_margin - pagination_width, footer_y), pagination_text, font=font, fill=(255, 255, 255))
            
            return canvas
        except Exception as e:
            logger.error(f"创建页脚层失败: {e}")
            import traceback
            traceback.print_exc()
            return None 