package com.moka.gdtauto.util;

import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * 视频水印工具类测试
 * 注意：视频处理需要较长时间，测试会生成测试视频文件
 *
 * @author moka
 */
@Slf4j
class VideoWatermarkUtilTest {

    private static final String TEST_OUTPUT_DIR = "target/test-output/video-watermark";
    private static final String TEST_INPUT_VIDEO = TEST_OUTPUT_DIR + "/test-input.mp4";

    @BeforeEach
    void setUp() throws Exception {
        // 创建测试输出目录
        File outputDir = new File(TEST_OUTPUT_DIR);
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        // 生成测试用的视频（5秒，30fps）
        if (!new File(TEST_INPUT_VIDEO).exists()) {
            createTestVideo(TEST_INPUT_VIDEO, 1280, 720, 30, 5);
        }
    }

    /**
     * 测试基本视频水印功能
     */
    @Test
    void testAddWatermark() throws Exception {
        String outputPath = TEST_OUTPUT_DIR + "/output-basic.mp4";
        String watermarkText = "《绝世龙王》";

        VideoWatermarkUtil.addWatermark(TEST_INPUT_VIDEO, outputPath, watermarkText);

        // 验证输出文件是否存在
        File outputFile = new File(outputPath);
        assert outputFile.exists() : "输出视频文件不存在";
        assert outputFile.length() > 0 : "输出视频文件为空";

        log.info("基本视频水印测试通过，输出文件: {}", outputPath);
    }

    /**
     * 测试自定义位置和字体大小
     */
    @Test
    void testAddWatermarkWithCustomSettings() throws Exception {
        String outputPath = TEST_OUTPUT_DIR + "/output-custom.mp4";
        String watermarkText = "《绝世龙王》";

        // 自定义：字体大小60，位置(100, 100)
        VideoWatermarkUtil.addWatermark(TEST_INPUT_VIDEO, outputPath, watermarkText, 60, 5, 100, 100);

        File outputFile = new File(outputPath);
        assert outputFile.exists() : "输出视频文件不存在";
        assert outputFile.length() > 0 : "输出视频文件为空";

        log.info("自定义设置视频水印测试通过，输出文件: {}", outputPath);
    }

    /**
     * 测试提取视频第一帧
     */
    @Test
    void testExtractFirstFrame() throws Exception {
        String outputPath = TEST_OUTPUT_DIR + "/first-frame.jpg";

        VideoWatermarkUtil.extractFirstFrame(TEST_INPUT_VIDEO, outputPath);

        File outputFile = new File(outputPath);
        assert outputFile.exists() : "提取的第一帧图片不存在";
        assert outputFile.length() > 0 : "提取的第一帧图片为空";

        log.info("提取第一帧测试通过，输出文件: {}", outputPath);
    }

    /**
     * 测试多个不同的剧名
     */
    @Test
    void testMultipleWatermarks() throws Exception {
        String[] dramaNames = {
                "《绝世龙王》",
                "《霸道总裁爱上我》"
        };

        for (int i = 0; i < dramaNames.length; i++) {
            String outputPath = TEST_OUTPUT_DIR + "/output-drama-" + i + ".mp4";
            VideoWatermarkUtil.addWatermark(TEST_INPUT_VIDEO, outputPath, dramaNames[i]);

            File outputFile = new File(outputPath);
            assert outputFile.exists() : "输出视频文件不存在: " + dramaNames[i];
            log.info("剧名 {} 视频水印添加成功", dramaNames[i]);
        }

        log.info("多剧名视频水印测试全部通过");
    }

    /**
     * 创建测试用的视频
     *
     * @param path      输出路径
     * @param width     宽度
     * @param height    高度
     * @param frameRate 帧率
     * @param duration  时长（秒）
     */
    @SuppressWarnings("resource")
    private void createTestVideo(String path, int width, int height, double frameRate, int duration) throws Exception {
        log.info("开始创建测试视频: {}, 尺寸: {}x{}, 帧率: {}, 时长: {}秒", path, width, height, frameRate, duration);

        FFmpegFrameRecorder recorder = null;
        Java2DFrameConverter converter = new Java2DFrameConverter();

        try {
            // 创建录制器
            recorder = new FFmpegFrameRecorder(path, width, height, 0); // 0 表示没有音频
            recorder.setVideoCodec(org.bytedeco.ffmpeg.global.avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameRate);
            recorder.setVideoBitrate(2000000);
            recorder.start();

            int totalFrames = (int) (frameRate * duration);

            // 生成每一帧
            for (int i = 0; i < totalFrames; i++) {
                BufferedImage image = createTestFrame(width, height, i, totalFrames);
                recorder.record(converter.convert(image));

                if (i % 30 == 0) {
                    log.info("创建测试视频进度: {}/{}", i, totalFrames);
                }
            }

            log.info("测试视频创建成功: {}", path);

        } finally {
            if (recorder != null) {
                try {
                    recorder.stop();
                    recorder.release();
                } catch (Exception e) {
                    log.error("关闭recorder失败", e);
                }
            }
            converter.close();
        }
    }

    /**
     * 创建测试帧
     */
    private BufferedImage createTestFrame(int width, int height, int frameIndex, int totalFrames) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();

        // 计算颜色（从蓝色渐变到青色）
        float progress = (float) frameIndex / totalFrames;
        Color startColor = Color.BLUE;
        Color endColor = Color.CYAN;
        int r = (int) (startColor.getRed() + (endColor.getRed() - startColor.getRed()) * progress);
        int g = (int) (startColor.getGreen() + (endColor.getGreen() - startColor.getGreen()) * progress);
        int b = (int) (startColor.getBlue() + (endColor.getBlue() - startColor.getBlue()) * progress);

        // 填充背景
        g2d.setColor(new Color(r, g, b));
        g2d.fillRect(0, 0, width, height);

        // 添加文字说明
        g2d.setColor(Color.WHITE);
        g2d.setFont(new Font("Arial", Font.BOLD, 36));
        String text = String.format("Test Video Frame %d/%d", frameIndex + 1, totalFrames);
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(text);
        g2d.drawString(text, (width - textWidth) / 2, height / 2);

        g2d.dispose();
        return image;
    }
}
