package com.example.demo.service;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * 图片网格拼接服务
 * 用于将多张分镜图片拼接成一个网格布局
 * 参考Comfly项目的图片处理方式
 */
@Service
public class ImageGridService {

    private static final Logger logger = LoggerFactory.getLogger(ImageGridService.class);

    /**
     * 将多张图片URL拼接成一个网格图片
     * 
     * @param imageUrls 图片URL列表
     * @param gridCols 网格列数，默认3列（适合6张或9张图）
     * @return Base64编码的拼接后图片
     */
    public String mergeImagesToGrid(List<String> imageUrls, int gridCols) {
        if (imageUrls == null || imageUrls.isEmpty()) {
            throw new IllegalArgumentException("图片URL列表不能为空");
        }

        try {
            int imageCount = imageUrls.size();
            // 自动计算网格布局：如果未指定列数，根据图片数量自动计算
            if (gridCols <= 0) {
                gridCols = calculateOptimalColumns(imageCount);
            }
            int gridRows = (int) Math.ceil((double) imageCount / gridCols);

            logger.info("开始拼接图片网格: 图片数量={}, 列数={}, 行数={}", imageCount, gridCols, gridRows);

            // 读取所有图片
            BufferedImage[] images = new BufferedImage[imageCount];
            int maxWidth = 512;  // 默认最小宽度，避免网格尺寸为0
            int maxHeight = 512; // 默认最小高度，避免网格尺寸为0

            for (int i = 0; i < imageCount; i++) {
                BufferedImage img = loadImageFromUrl(imageUrls.get(i));
                if (img != null) {
                    images[i] = img;
                    maxWidth = Math.max(maxWidth, img.getWidth());
                    maxHeight = Math.max(maxHeight, img.getHeight());
                } else {
                    logger.warn("无法加载图片: {}", imageUrls.get(i));
                    // 创建一个空白图片占位
                    BufferedImage placeholder = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
                    Graphics2D g = placeholder.createGraphics();
                    g.setColor(java.awt.Color.WHITE);
                    g.fillRect(0, 0, 512, 512);
                    g.dispose();
                    images[i] = placeholder;
                }
            }

            // 创建网格图片
            // 对于6宫格（3列2行），强制整体比例为16:9
            int cellWidth = maxWidth;
            int cellHeight = maxHeight;
            
            // 6宫格特殊处理：3列2行，整体16:9
            // 16:9 = (3*cellWidth):(2*cellHeight)
            // cellWidth:cellHeight = 32:27
            if (imageCount == 6 && gridCols == 3 && gridRows == 2) {
                // 基于最大尺寸计算16:9整体比例的单元格尺寸
                int baseSize = Math.max(maxWidth, maxHeight);
                cellWidth = (int)(baseSize * 32.0 / 27.0);  // 32:27比例
                cellHeight = baseSize;
                logger.info("6宫格使用16:9比例，单元格尺寸: {}x{}", cellWidth, cellHeight);
            }
            
            BufferedImage gridImage = new BufferedImage(
                gridCols * cellWidth,
                gridRows * cellHeight,
                BufferedImage.TYPE_INT_RGB
            );

            Graphics2D g = gridImage.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g.setColor(java.awt.Color.BLACK);  // 黑色背景
            g.fillRect(0, 0, gridImage.getWidth(), gridImage.getHeight());

            // 将图片放置到网格中
            for (int i = 0; i < imageCount; i++) {
                int row = i / gridCols;
                int col = i % gridCols;
                int x = col * cellWidth;
                int y = row * cellHeight;

                BufferedImage img = images[i];
                // 缩放图片以适应单元格，保持比例居中
                double scaleX = (double) cellWidth / img.getWidth();
                double scaleY = (double) cellHeight / img.getHeight();
                double scale = Math.min(scaleX, scaleY);
                int scaledWidth = (int)(img.getWidth() * scale);
                int scaledHeight = (int)(img.getHeight() * scale);
                int imgX = x + (cellWidth - scaledWidth) / 2;
                int imgY = y + (cellHeight - scaledHeight) / 2;
                
                g.drawImage(img, imgX, imgY, scaledWidth, scaledHeight, null);
            }

            g.dispose();

            // 压缩网格图片以减小体积（限制最大尺寸）
            BufferedImage compressedGrid = compressGridImage(gridImage, 2048); // 网格图最大2048px
            
            // 转换为JPEG格式的Base64（JPEG压缩率更高，体积更小）
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            javax.imageio.ImageWriter writer = javax.imageio.ImageIO.getImageWritersByFormatName("jpg").next();
            javax.imageio.ImageWriteParam param = writer.getDefaultWriteParam();
            if (param.canWriteCompressed()) {
                param.setCompressionMode(javax.imageio.ImageWriteParam.MODE_EXPLICIT);
                param.setCompressionQuality(0.85f); // JPEG质量85%
            }
            javax.imageio.IIOImage iioImage = new javax.imageio.IIOImage(compressedGrid, null, null);
            writer.setOutput(javax.imageio.ImageIO.createImageOutputStream(baos));
            writer.write(null, iioImage, param);
            writer.dispose();
            
            byte[] imageBytes = baos.toByteArray();
            String base64 = Base64.getEncoder().encodeToString(imageBytes);
            
            logger.info("图片网格拼接完成: 原始尺寸={}x{}, 压缩后尺寸={}x{}, 大小={} KB", 
                gridImage.getWidth(), gridImage.getHeight(),
                compressedGrid.getWidth(), compressedGrid.getHeight(),
                imageBytes.length / 1024);
            
            return "data:image/jpeg;base64," + base64;

        } catch (Exception e) {
            logger.error("拼接图片网格失败", e);
            throw new RuntimeException("图片拼接失败: " + e.getMessage(), e);
        }
    }

    /**
     * 计算最优列数
     */
    private int calculateOptimalColumns(int imageCount) {
        // 根据图片数量选择最佳列数
        if (imageCount <= 2) return 2;
        if (imageCount <= 4) return 2;
        if (imageCount <= 6) return 3;
        if (imageCount <= 9) return 3;
        if (imageCount <= 12) return 4;
        return 4; // 默认4列
    }

    /**
     * 压缩网格图片以减小体积
     * @param originalImage 原始图片
     * @param maxSize 最大尺寸（宽度或高度）
     * @return 压缩后的图片
     */
    private BufferedImage compressGridImage(BufferedImage originalImage, int maxSize) {
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
        
        // 如果图片尺寸小于等于最大尺寸，直接返回
        if (originalWidth <= maxSize && originalHeight <= maxSize) {
            return originalImage;
        }
        
        // 计算缩放比例
        double scale = Math.min((double) maxSize / originalWidth, (double) maxSize / originalHeight);
        int newWidth = (int) (originalWidth * scale);
        int newHeight = (int) (originalHeight * scale);
        
        logger.debug("压缩网格图片: {}x{} -> {}x{} (缩放比例: {})", 
            originalWidth, originalHeight, newWidth, newHeight, scale);
        
        // 创建缩放后的图片
        BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = compressedImage.createGraphics();
        
        // 设置高质量缩放
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        g.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
        g.dispose();
        
        return compressedImage;
    }
    
    /**
     * 拼接分镜图：将用户上传的原图和AI生成的分镜图拼接在一起
     * 
     * 规则：
     * - 如果原图是16:9（横向），创建9:16的画布，原图在左，生成图在右
     * - 如果原图是9:16（纵向），创建16:9的画布，原图在上，生成图在下
     * 
     * @param originalImageUrl 用户上传的原图URL或Base64
     * @param generatedImageUrl AI生成的分镜图URL或Base64
     * @return 拼接后的图片Base64
     */
    public String mergeStoryboardImages(String originalImageUrl, String generatedImageUrl) {
        if (originalImageUrl == null || originalImageUrl.isEmpty()) {
            throw new IllegalArgumentException("原图不能为空");
        }
        if (generatedImageUrl == null || generatedImageUrl.isEmpty()) {
            throw new IllegalArgumentException("生成图不能为空");
        }

        try {
            // 加载原图和生成图
            BufferedImage originalImage = loadImageFromUrl(originalImageUrl);
            BufferedImage generatedImage = loadImageFromUrl(generatedImageUrl);

            if (originalImage == null) {
                throw new RuntimeException("无法加载原图");
            }
            if (generatedImage == null) {
                throw new RuntimeException("无法加载生成图");
            }

            int origWidth = originalImage.getWidth();
            int origHeight = originalImage.getHeight();
            double aspectRatio = (double) origWidth / origHeight;

            logger.info("分镜图拼接: 原图尺寸={}x{}, 宽高比={:.2f}, 生成图尺寸={}x{}", 
                origWidth, origHeight, aspectRatio, 
                generatedImage.getWidth(), generatedImage.getHeight());

            BufferedImage resultImage;
            Graphics2D g;

            // 判断原图是横向(16:9)还是纵向(9:16)
            if (aspectRatio >= 1.0) {
                // 横向图片（16:9或更宽）：创建9:16的画布，左右拼接
                // 画布宽度 = 原图宽度，画布高度 = 画布宽度 * 16 / 9
                int canvasWidth = origWidth;
                int canvasHeight = (int) (canvasWidth * 16.0 / 9.0);
                
                // 每张图片占画布宽度的一半
                int halfWidth = canvasWidth / 2;
                int imageHeight = canvasHeight;
                
                resultImage = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB);
                g = resultImage.createGraphics();
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                
                // 白色背景
                g.setColor(java.awt.Color.WHITE);
                g.fillRect(0, 0, canvasWidth, canvasHeight);
                
                // 左侧放原图（缩放并居中）
                drawImageCentered(g, originalImage, 0, 0, halfWidth, imageHeight);
                
                // 右侧放生成图（缩放并居中）
                drawImageCentered(g, generatedImage, halfWidth, 0, halfWidth, imageHeight);
                
                logger.info("横向拼接完成: 画布={}x{}, 每张图={}x{}", canvasWidth, canvasHeight, halfWidth, imageHeight);
                
            } else {
                // 纵向图片（9:16或更窄）：创建16:9的画布，上下拼接
                // 画布高度 = 原图高度，画布宽度 = 画布高度 * 16 / 9
                int canvasHeight = origHeight;
                int canvasWidth = (int) (canvasHeight * 16.0 / 9.0);
                
                // 每张图片占画布高度的一半
                int halfHeight = canvasHeight / 2;
                int imageWidth = canvasWidth;
                
                resultImage = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB);
                g = resultImage.createGraphics();
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                
                // 白色背景
                g.setColor(java.awt.Color.WHITE);
                g.fillRect(0, 0, canvasWidth, canvasHeight);
                
                // 上侧放原图（缩放并居中）
                drawImageCentered(g, originalImage, 0, 0, imageWidth, halfHeight);
                
                // 下侧放生成图（缩放并居中）
                drawImageCentered(g, generatedImage, 0, halfHeight, imageWidth, halfHeight);
                
                logger.info("纵向拼接完成: 画布={}x{}, 每张图={}x{}", canvasWidth, canvasHeight, imageWidth, halfHeight);
            }

            g.dispose();

            // 压缩并转换为Base64
            BufferedImage compressedImage = compressGridImage(resultImage, 2048);
            
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            javax.imageio.ImageWriter writer = javax.imageio.ImageIO.getImageWritersByFormatName("jpg").next();
            javax.imageio.ImageWriteParam param = writer.getDefaultWriteParam();
            if (param.canWriteCompressed()) {
                param.setCompressionMode(javax.imageio.ImageWriteParam.MODE_EXPLICIT);
                param.setCompressionQuality(0.85f);
            }
            javax.imageio.IIOImage iioImage = new javax.imageio.IIOImage(compressedImage, null, null);
            writer.setOutput(javax.imageio.ImageIO.createImageOutputStream(baos));
            writer.write(null, iioImage, param);
            writer.dispose();
            
            byte[] imageBytes = baos.toByteArray();
            String base64 = Base64.getEncoder().encodeToString(imageBytes);
            
            logger.info("分镜图拼接完成: 最终尺寸={}x{}, 大小={} KB", 
                compressedImage.getWidth(), compressedImage.getHeight(), imageBytes.length / 1024);
            
            return "data:image/jpeg;base64," + base64;

        } catch (Exception e) {
            logger.error("拼接分镜图失败", e);
            throw new RuntimeException("分镜图拼接失败: " + e.getMessage(), e);
        }
    }

    /**
     * 在指定区域内居中绘制图片（保持比例，不裁切）
     */
    private void drawImageCentered(Graphics2D g, BufferedImage img, int x, int y, int width, int height) {
        double scaleX = (double) width / img.getWidth();
        double scaleY = (double) height / img.getHeight();
        double scale = Math.min(scaleX, scaleY);
        
        int scaledWidth = (int) (img.getWidth() * scale);
        int scaledHeight = (int) (img.getHeight() * scale);
        int imgX = x + (width - scaledWidth) / 2;
        int imgY = y + (height - scaledHeight) / 2;
        
        logger.debug("drawImageCentered: 原图={}x{}, 目标区域={}x{}, 缩放后={}x{}, 位置=({},{})", 
            img.getWidth(), img.getHeight(), width, height, scaledWidth, scaledHeight, imgX, imgY);
        
        g.drawImage(img, imgX, imgY, scaledWidth, scaledHeight, null);
    }
    
    /**
     * 在指定区域内填充绘制图片（拉伸填充，可能变形）
     */
    private void drawImageFill(Graphics2D g, BufferedImage img, int x, int y, int width, int height) {
        g.drawImage(img, x, y, width, height, null);
    }
    
    /**
     * 在指定区域内裁切填充绘制图片（保持比例，裁切多余部分）
     */
    private void drawImageCover(Graphics2D g, BufferedImage img, int x, int y, int width, int height) {
        double scaleX = (double) width / img.getWidth();
        double scaleY = (double) height / img.getHeight();
        double scale = Math.max(scaleX, scaleY);  // 使用较大的缩放比例
        
        int scaledWidth = (int) (img.getWidth() * scale);
        int scaledHeight = (int) (img.getHeight() * scale);
        int imgX = x + (width - scaledWidth) / 2;
        int imgY = y + (height - scaledHeight) / 2;
        
        g.drawImage(img, imgX, imgY, scaledWidth, scaledHeight, null);
    }

    /**
     * 从URL加载图片
     */
    private BufferedImage loadImageFromUrl(String imageUrl) {
        try {
            // 处理base64格式的图片
            if (imageUrl.startsWith("data:image")) {
                String base64Data = imageUrl.substring(imageUrl.indexOf(",") + 1);
                byte[] imageBytes = Base64.getDecoder().decode(base64Data);
                return ImageIO.read(new java.io.ByteArrayInputStream(imageBytes));
            }
            
            // 处理普通URL
            URI uri = new URI(imageUrl);
            URL url = uri.toURL();
            return ImageIO.read(url);
        } catch (IOException | URISyntaxException e) {
            logger.error("加载图片失败: {}", imageUrl, e);
            return null;
        }
    }

    /**
     * 创建分镜图布局
     * 
     * 规则（注意：画布比例与用户选择相反）：
     * - 用户选择16:9 → 创建9:16竖屏画布，上下2:1分割
     *   - 无上传图：banana生成9:16分镜图，填充整个画布
     *   - 有上传图：banana生成4:3分镜图放上侧，下侧从左到右放用户图片（每份比例9:16）
     * - 用户选择9:16 → 创建16:9横屏画布，左右3:1分割
     *   - 无上传图：banana生成16:9分镜图，填充整个画布
     *   - 有上传图：banana生成4:3分镜图放左侧，右侧从上到下放用户图片（每份比例16:9）
     * 
     * @param generatedImage 生成的分镜图Base64
     * @param uploadedImages 用户上传的图片列表（最多3张）
     * @param aspectRatio 用户选择的比例（16:9 或 9:16）
     * @return 合成后的图片Base64
     */
    public String createStoryboardLayout(String generatedImage, List<String> uploadedImages, String aspectRatio) {
        try {
            // 画布比例与用户选择一致（修复：之前是相反的，导致Sora2裁剪时丢失参考图）
            // 用户选择16:9 → 画布是16:9横屏；用户选择9:16 → 画布是9:16竖屏
            boolean userSelected16x9 = "16:9".equals(aspectRatio);
            boolean canvasIsHorizontal = userSelected16x9; // 修复：与用户选择一致
            
            // 基础画布尺寸 - 使用标准尺寸
            int baseWidth, baseHeight;
            if (canvasIsHorizontal) {
                // 16:9 横屏画布：1920x1080
                baseWidth = 1920;
                baseHeight = 1080;
            } else {
                // 9:16 竖屏画布：1080x1920
                baseWidth = 1080;
                baseHeight = 1920;
            }
            
            // 过滤掉null和空字符串
            List<String> validUploads = new ArrayList<>();
            if (uploadedImages != null) {
                for (String img : uploadedImages) {
                    if (img != null && !img.isEmpty() && !"null".equals(img)) {
                        validUploads.add(img);
                    }
                }
            }
            boolean hasUploads = !validUploads.isEmpty();
            
            logger.info("创建分镜图布局: 用户选择={}, 画布比例={}, hasUploads={}, uploadCount={}, 画布尺寸={}x{}", 
                aspectRatio, canvasIsHorizontal ? "16:9横屏" : "9:16竖屏", hasUploads, validUploads.size(), baseWidth, baseHeight);
            
            // 加载生成的分镜图
            BufferedImage storyboardImg = loadImageFromUrl(generatedImage);
            if (storyboardImg == null) {
                throw new RuntimeException("无法加载生成的分镜图");
            }
            
            // 创建白色底图
            BufferedImage canvas = new BufferedImage(baseWidth, baseHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = canvas.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            
            // 填充白色背景
            g.setColor(java.awt.Color.WHITE);
            g.fillRect(0, 0, baseWidth, baseHeight);
            
            if (!hasUploads) {
                // 无上传图片：分镜图保持比例居中填充整个画布
                drawImageCentered(g, storyboardImg, 0, 0, baseWidth, baseHeight);
                logger.info("无上传图片，分镜图居中填充整个画布");
            } else if (canvasIsHorizontal) {
                // 用户选择16:9 → 16:9横屏画布，有上传图：左右布局（3:1）
                int leftWidth = baseWidth * 3 / 4;  // 左侧占3/4
                int rightWidth = baseWidth - leftWidth;  // 右侧占1/4
                
                // 左侧放分镜图（保持比例居中）
                drawImageCentered(g, storyboardImg, 0, 0, leftWidth, baseHeight);
                
                // 右侧从上到下放用户图片（最多3张，每份比例16:9）
                int userImageCount = Math.min(validUploads.size(), 3);
                int cellHeight = baseHeight / 3;  // 每张图片区域高度
                int cellWidth = rightWidth;  // 每张图片区域宽度
                
                for (int i = 0; i < userImageCount; i++) {
                    BufferedImage userImg = loadImageFromUrl(validUploads.get(i));
                    if (userImg != null) {
                        int y = i * cellHeight;
                        // 在单元格内居中绘制用户图片（带白色边框效果）
                        drawUserImageWithBorder(g, userImg, leftWidth, y, cellWidth, cellHeight, "16:9");
                    }
                }
                
                logger.info("用户选16:9→16:9横屏布局完成: 左侧={}px, 右侧={}px, 用户图片数={}", leftWidth, rightWidth, userImageCount);
            } else {
                // 用户选择9:16 → 9:16竖屏画布，有上传图：上下布局（2:1）
                int topHeight = baseHeight * 2 / 3;  // 上侧占2/3
                int bottomHeight = baseHeight - topHeight;  // 下侧占1/3
                
                // 上侧放分镜图（保持比例居中）
                drawImageCentered(g, storyboardImg, 0, 0, baseWidth, topHeight);
                
                // 下侧从左到右放用户图片（最多3张，每份比例9:16）
                int userImageCount = Math.min(validUploads.size(), 3);
                int cellWidth = baseWidth / 3;  // 每张图片区域宽度
                int cellHeight = bottomHeight;  // 每张图片区域高度
                
                for (int i = 0; i < userImageCount; i++) {
                    BufferedImage userImg = loadImageFromUrl(validUploads.get(i));
                    if (userImg != null) {
                        int x = i * cellWidth;
                        // 在单元格内居中绘制用户图片（带白色边框效果）
                        drawUserImageWithBorder(g, userImg, x, topHeight, cellWidth, cellHeight, "9:16");
                    }
                }
                
                logger.info("用户选9:16→9:16竖屏布局完成: 上侧={}px, 下侧={}px, 用户图片数={}", topHeight, bottomHeight, userImageCount);
            }
            
            g.dispose();
            
            // 压缩并转换为Base64
            BufferedImage compressedImage = compressGridImage(canvas, 2048);
            
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            javax.imageio.ImageWriter writer = javax.imageio.ImageIO.getImageWritersByFormatName("jpg").next();
            javax.imageio.ImageWriteParam param = writer.getDefaultWriteParam();
            if (param.canWriteCompressed()) {
                param.setCompressionMode(javax.imageio.ImageWriteParam.MODE_EXPLICIT);
                param.setCompressionQuality(0.85f);
            }
            javax.imageio.IIOImage iioImage = new javax.imageio.IIOImage(compressedImage, null, null);
            writer.setOutput(javax.imageio.ImageIO.createImageOutputStream(baos));
            writer.write(null, iioImage, param);
            writer.dispose();
            
            byte[] imageBytes = baos.toByteArray();
            String base64 = Base64.getEncoder().encodeToString(imageBytes);
            
            logger.info("分镜图布局完成: 最终尺寸={}x{}, 大小={} KB", 
                compressedImage.getWidth(), compressedImage.getHeight(), imageBytes.length / 1024);
            
            return "data:image/jpeg;base64," + base64;
            
        } catch (Exception e) {
            logger.error("创建分镜图布局失败", e);
            throw new RuntimeException("创建分镜图布局失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 在单元格内绘制用户图片，并确保图片+白色边框的比例符合要求
     * @param g 画布
     * @param img 用户图片
     * @param x 单元格X坐标
     * @param y 单元格Y坐标
     * @param cellWidth 单元格宽度
     * @param cellHeight 单元格高度
     * @param targetRatio 目标比例（16:9 或 9:16）
     */
    private void drawUserImageWithBorder(Graphics2D g, BufferedImage img, int x, int y, 
            int cellWidth, int cellHeight, String targetRatio) {
        // 在单元格内留白边框（10%边距）
        int margin = Math.min(cellWidth, cellHeight) / 20;
        int innerX = x + margin;
        int innerY = y + margin;
        int innerWidth = cellWidth - margin * 2;
        int innerHeight = cellHeight - margin * 2;
        
        // 绘制白色底图（单元格背景已经是白色）
        // 在内部区域居中绘制用户图片
        drawImageCentered(g, img, innerX, innerY, innerWidth, innerHeight);
    }
    
    /**
     * 根据是否有上传图片，返回生成分镜图时应使用的比例
     * 
     * 规则（画布比例与用户选择相反）：
     * - 用户选择16:9 → 画布是9:16 → 无上传图时生成9:16分镜图
     * - 用户选择9:16 → 画布是16:9 → 无上传图时生成16:9分镜图
     * - 有上传图时：统一使用4:3
     * 
     * @param targetAspectRatio 用户选择的比例（16:9 或 9:16）
     * @param hasUploads 是否有用户上传的图片
     * @return 生成分镜图应使用的比例
     */
    public String getGenerationAspectRatio(String targetAspectRatio, boolean hasUploads) {
        if (!hasUploads) {
            // 无上传图片：使用与用户选择相反的比例（因为画布比例相反）
            if ("16:9".equals(targetAspectRatio)) {
                return "9:16";  // 用户选16:9 → 画布是9:16 → 生成9:16分镜图
            } else {
                return "16:9";  // 用户选9:16 → 画布是16:9 → 生成16:9分镜图
            }
        } else {
            // 有上传图片：使用4:3生成分镜图
            return "4:3";
        }
    }
}

