package com.ruoyi.common.utils;



import com.ruoyi.common.utils.file.FileUploadUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * 视频处理工具类（基于JavaCV）
 *
 * @author ruoyi
 */
public class VideoUtils
{
    private static final Logger log = LoggerFactory.getLogger(VideoUtils.class);

    /**
     * 获取视频信息
     *
     * @param videoPath 视频文件路径
     * @return 视频信息Map，包含duration（时长秒）、width（宽度）、height（高度）
     */
    public static Map<String, Object> getVideoInfo(String videoPath)
    {
        Map<String, Object> videoInfo = new HashMap<>();
        FFmpegFrameGrabber grabber = null;

        try
        {
            grabber = new FFmpegFrameGrabber(videoPath);
            grabber.start();

            // 获取视频时长（微秒转换为秒）
            long durationMicroseconds = grabber.getLengthInTime();
            if (durationMicroseconds > 0)
            {
                long durationSeconds = durationMicroseconds / 1000000;
                videoInfo.put("durationSeconds", durationSeconds);
            }

            // 获取视频帧数
            int frameNumber = grabber.getLengthInFrames();

            // 获取视频宽度和高度
            int width = grabber.getImageWidth();
            int height = grabber.getImageHeight();

            if (width > 0 && height > 0)
            {
                videoInfo.put("resolution", width + "x" + height);
                videoInfo.put("width", width);
                videoInfo.put("height", height);
            }

            // 获取帧率
            double frameRate = grabber.getFrameRate();
            if (frameRate > 0)
            {
                videoInfo.put("frameRate", frameRate);
            }
        }
        catch (Exception e)
        {
            log.error("获取视频信息失败: {}", videoPath, e);
        }
        finally
        {
            if (grabber != null)
            {
                try
                {
                    grabber.stop();
                    grabber.release();
                }
                catch (Exception e)
                {
                    log.warn("释放视频资源失败", e);
                }
            }
        }

        return videoInfo;
    }

    /**
     * 获取视频时长（秒）
     *
     * @param videoPath 视频文件路径
     * @return 时长（秒），失败返回null
     */
    public static Long getVideoDuration(String videoPath)
    {
        Map<String, Object> videoInfo = getVideoInfo(videoPath);
        return (Long) videoInfo.get("durationSeconds");
    }

    /**
     * 获取视频分辨率
     *
     * @param videoPath 视频文件路径
     * @return 分辨率（如1920x1080），失败返回null
     */
    public static String getVideoResolution(String videoPath)
    {
        Map<String, Object> videoInfo = getVideoInfo(videoPath);
        return (String) videoInfo.get("resolution");
    }

    /**
     * 从视频文件生成缩略图
     *
     * @param videoPath 视频文件路径
     * @return 缩略图文件路径，如果生成失败返回null
     */
    public static String generateVideoThumbnail(String videoPath)
    {
        return generateVideoThumbnail(videoPath, 1);
    }

    /**
     * 从视频文件生成缩略图
     *
     * @param videoPath 视频文件路径
     * @param captureTime 截取时间点（秒）
     * @return 缩略图文件路径，如果生成失败返回null
     */
    public static String generateVideoThumbnail(String videoPath, int captureTime)
    {
        return generateVideoThumbnail(videoPath, captureTime, 200, 200);
    }

    /**
     * 从视频文件生成缩略图（自定义尺寸）
     *
     * @param videoPath 视频文件路径
     * @param captureTime 截取时间点（秒）
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @return 缩略图文件路径，如果生成失败返回null
     */
    public static String generateVideoThumbnail(String videoPath, int captureTime, int width, int height)
    {
        FFmpegFrameGrabber grabber = null;
        Java2DFrameConverter converter = null;

        try
        {
            grabber = new FFmpegFrameGrabber(videoPath);
            grabber.start();

            // 计算目标帧位置
            int frameNumber = (int) (captureTime * grabber.getFrameRate());
            if (frameNumber >= grabber.getLengthInFrames())
            {
                frameNumber = grabber.getLengthInFrames() - 1;
            }

            // 跳转到指定帧
            grabber.setFrameNumber(frameNumber);
            Frame frame = grabber.grabImage();

            if (frame == null)
            {
                log.warn("无法抓取视频帧: {}", videoPath);
                return null;
            }

            // 转换Frame为BufferedImage
            converter = new Java2DFrameConverter();
            BufferedImage bufferedImage = converter.convert(frame);

            if (bufferedImage == null)
            {
                log.warn("转换视频帧失败: {}", videoPath);
                return null;
            }

            // 缩放图片
            BufferedImage thumbnail = resizeImage(bufferedImage, width, height);

            // 生成缩略图文件名
            String extension = "jpg";
            String thumbnailFileName = "thumb_" + com.ruoyi.common.utils.uuid.IdUtils.fastSimpleUUID() + "." + extension;
            String datePath = com.ruoyi.common.utils.DateUtils.datePath();
            String thumbnailPath = datePath + "/" + thumbnailFileName;

            // 保存缩略图
            String uploadDir = com.ruoyi.common.config.RuoYiConfig.getUploadPath();
            File thumbnailFile = FileUploadUtils.getAbsoluteFile(uploadDir, thumbnailPath);
            ImageIO.write(thumbnail, extension, thumbnailFile);

            // 返回访问路径
            return FileUploadUtils.getPathFileName(uploadDir, thumbnailPath);
        }
        catch (Exception e)
        {
            log.error("生成视频缩略图失败: {}", videoPath, e);
            return null;
        }
        finally
        {
            if (converter != null)
            {
                converter.close();
            }
            if (grabber != null)
            {
                try
                {
                    grabber.stop();
                    grabber.release();
                }
                catch (Exception e)
                {
                    log.warn("释放视频资源失败", e);
                }
            }
        }
    }

    /**
     * 缩放图片（保持宽高比）
     *
     * @param original 原始图片
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @return 缩放后的图片
     */
    private static BufferedImage resizeImage(BufferedImage original, int targetWidth, int targetHeight)
    {
        int originalWidth = original.getWidth();
        int originalHeight = original.getHeight();

        // 计算缩放比例，保持宽高比
        double scale = Math.min((double) targetWidth / originalWidth, (double) targetHeight / originalHeight);
        int scaledWidth = (int) (originalWidth * scale);
        int scaledHeight = (int) (originalHeight * scale);

        // 创建缩放后的图片
        BufferedImage resized = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
        java.awt.Graphics2D g2d = resized.createGraphics();

        // 设置图片平滑渲染
        g2d.setRenderingHint(java.awt.RenderingHints.KEY_INTERPOLATION,
                java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.drawImage(original.getScaledInstance(scaledWidth, scaledHeight, java.awt.Image.SCALE_SMOOTH),
                0, 0, null);
        g2d.dispose();

        return resized;
    }
}
