package com.ycwl.basic.image.pipeline.stages;

import com.ycwl.basic.image.pipeline.core.PhotoProcessContext;
import com.ycwl.basic.pipeline.annotation.StageConfig;
import com.ycwl.basic.pipeline.core.AbstractPipelineStage;
import com.ycwl.basic.pipeline.core.StageResult;
import com.ycwl.basic.pipeline.enums.StageOptionalMode;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * 图像缩放Stage
 * 支持按比例放大或缩小图片
 */
@Slf4j
@StageConfig(
    stageId = "image_resize",
    optionalMode = StageOptionalMode.SUPPORT,
    description = "图像缩放处理",
    defaultEnabled = true
)
public class ImageResizeStage extends AbstractPipelineStage<PhotoProcessContext> {

    private final double scaleFactor;

    /**
     * 构造函数
     * @param scaleFactor 缩放比例(例如: 1.5表示放大1.5倍, 0.333表示缩小到1/3)
     */
    public ImageResizeStage(double scaleFactor) {
        if (scaleFactor <= 0) {
            throw new IllegalArgumentException("scaleFactor must be positive");
        }
        this.scaleFactor = scaleFactor;
    }

    @Override
    public String getName() {
        return "ImageResizeStage";
    }

    @Override
    protected StageResult<PhotoProcessContext> doExecute(PhotoProcessContext context) {
        File currentFile = context.getCurrentFile();
        if (currentFile == null || !currentFile.exists()) {
            return StageResult.skipped("当前文件不存在");
        }

        BufferedImage originalImage = null;
        BufferedImage resizedImage = null;

        try {
            log.debug("开始图像缩放处理: file={}, scaleFactor={}", currentFile.getName(), scaleFactor);

            // 读取原图
            originalImage = ImageIO.read(currentFile);
            if (originalImage == null) {
                return StageResult.failed("无法读取图片文件");
            }

            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();

            // 计算新尺寸
            int newWidth = (int) Math.round(originalWidth * scaleFactor);
            int newHeight = (int) Math.round(originalHeight * scaleFactor);

            // 检查尺寸是否合理
            if (newWidth <= 0 || newHeight <= 0) {
                return StageResult.failed("缩放后尺寸无效: " + newWidth + "x" + newHeight);
            }

            // 创建缩放后的图像
            resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = resizedImage.createGraphics();

            try {
                // 设置高质量渲染选项
                g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 执行缩放
                g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
            } finally {
                g2d.dispose();
            }

            // 保存缩放后的图片
            File resizedFile = context.getTempFileManager().createTempFile("resized", ".jpg");
            ImageIO.write(resizedImage, "jpg", resizedFile);

            if (!resizedFile.exists() || resizedFile.length() == 0) {
                return StageResult.failed("缩放后图片保存失败");
            }

            // 更新处理后的文件
            context.updateProcessedFile(resizedFile);

            log.info("图像缩放完成: {}x{} -> {}x{} (比例: {})",
                    originalWidth, originalHeight,
                    newWidth, newHeight,
                    scaleFactor);

            return StageResult.success(String.format("缩放完成 (%dx%d -> %dx%d)",
                    originalWidth, originalHeight, newWidth, newHeight));

        } catch (Exception e) {
            log.error("图像缩放失败: {}", e.getMessage(), e);
            return StageResult.failed("缩放失败: " + e.getMessage(), e);
        } finally {
            // 释放图像资源
            if (originalImage != null) {
                originalImage.flush();
            }
            if (resizedImage != null) {
                resizedImage.flush();
            }
        }
    }
}
