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

import com.ycwl.basic.image.pipeline.core.PhotoProcessContext;
import com.ycwl.basic.image.pipeline.enums.ImageType;
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 com.ycwl.basic.utils.ImageUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.File;

/**
 * 恢复图片方向Stage
 * 如果之前旋转过图片,现在反向旋转恢复原方向
 * - rotation=90 时恢复需要旋转270度
 * - rotation=270 时恢复需要旋转90度
 */
@Slf4j
@StageConfig(
    stageId = "restore",
    optionalMode = StageOptionalMode.UNSUPPORT,
    description = "恢复竖图方向"
)
public class RestoreOrientationStage extends AbstractPipelineStage<PhotoProcessContext> {

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

    @Override
    protected boolean shouldExecuteByBusinessLogic(PhotoProcessContext context) {
        return context.getImageType() == ImageType.NORMAL_PHOTO && context.isRotationApplied();
    }

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

            Integer rotation = context.getImageRotation();
            if (rotation == null) {
                return StageResult.skipped("无旋转信息");
            }

            // 计算恢复旋转需要的角度(反向旋转)
            int restoreAngle = getRestoreAngle(rotation);

            String extension = getFileExtension(currentFile);
            File finalFile = context.getTempFileManager()
                    .createTempFile("final", extension);

            log.debug("恢复图片方向(旋转{}度): {} -> {}", restoreAngle, currentFile.getName(), finalFile.getName());
            rotateByAngle(currentFile, finalFile, restoreAngle);

            if (!finalFile.exists()) {
                return StageResult.failed("旋转后的文件未生成");
            }

            context.updateProcessedFile(finalFile);
            log.info("图片方向已恢复(旋转{}度)", restoreAngle);

            return StageResult.success("已恢复原方向");

        } catch (Exception e) {
            log.error("图片旋转失败", e);
            return StageResult.failed("旋转失败: " + e.getMessage(), e);
        }
    }

    /**
     * 计算恢复方向需要的旋转角度
     * @param originalRotation 原始旋转角度
     * @return 恢复需要的旋转角度
     */
    private int getRestoreAngle(int originalRotation) {
        // rotation=90 时，恢复需要旋转270度 (360-90=270)
        // rotation=270 时，恢复需要旋转90度 (360-270=90)
        // rotation=180 时，恢复需要旋转180度 (360-180=180)
        return (360 - originalRotation) % 360;
    }

    /**
     * 根据角度旋转图片
     */
    private void rotateByAngle(File input, File output, int angle) throws Exception {
        switch (angle) {
            case 90:
                ImageUtils.rotateImage90(input, output);
                break;
            case 180:
                ImageUtils.rotateImage180(input, output);
                break;
            case 270:
                ImageUtils.rotateImage270(input, output);
                break;
            default:
                break;
        }
    }

    private String getFileExtension(File file) {
        String name = file.getName();
        int lastDot = name.lastIndexOf('.');
        if (lastDot > 0) {
            return name.substring(lastDot);
        }
        return ".jpg";
    }
}
