using FFMpegCore.Enums;
using FFMpegCore.Helpers;
using FFMpegCore;
using System.IO;
using System.Security.Cryptography;

namespace VideoConcat.Common.Tools
{
    internal class VideoCombine
    {

        public static List<string> mustClearPath = [];

        /// <summary>
        /// 生成所有组合
        /// </summary>
        public static void GenerateCombinations(List<List<string>> videoLists, int index, List<string> currentCombination, List<List<string>> result)
        {
            if (index == videoLists.Count)
            {
                result.Add([.. currentCombination]);
                return;
            }


            foreach (string video in videoLists[index])
            {
                currentCombination.Add(video);
                GenerateCombinations(videoLists, index + 1, currentCombination, result);
                currentCombination.RemoveAt(currentCombination.Count - 1);
            }
        }

        /// <summary>
        /// 清理临时文件
        /// </summary>
        public static void Cleanup(List<string> pathList)
        {
            foreach (var path in pathList)
            {
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
            }
        }

        /// <summary>
        /// 将视频文件转换为ts格式
        /// </summary>
        public static string ConvertVideos(string videoPath)
        {

            var video = FFProbe.Analyse(videoPath);

            string mediaInfo = "";

            mediaInfo += $"视频: {videoPath}";
            mediaInfo += $"时长: {video.Duration}";
            mediaInfo += $"格式: {video.Format}";
            // 视频流信息
            foreach (var videoStream in video.VideoStreams)
            {
                mediaInfo += $"视频编码: {videoStream.CodecName}, 分辨率: {videoStream.Width}x{videoStream.Height}";
            }
            // 音频流信息
            foreach (var audioStream in video.AudioStreams)
            {
                mediaInfo += $"音频编码: {audioStream.CodecName}, 采样率: {audioStream.SampleRateHz} Hz";
            }

            LogUtils.Info(mediaInfo);


            FFMpegHelper.ConversionSizeExceptionCheck(video);

            string _tempMd5Name = GetLargeFileMD5(videoPath);

            //GlobalFFOptions.Current.TemporaryFilesFolder
            var destinationPath = Path.Combine(Path.GetTempPath(), $"{_tempMd5Name}{FileExtension.Ts}");

            if (File.Exists(destinationPath))
            {
                return destinationPath;
            }

            //Directory.CreateDirectory(GlobalFFOptions.Current.TemporaryFilesFolder);
            try
            {
                FFMpeg.Convert(videoPath, destinationPath, VideoType.Ts);
            }
            catch (Exception ex)
            {

                LogUtils.Info("视频转换失败！尝试另外一种转换");
                // 创建FFmpeg参数
                try
                {
                   // string _tempPathError = Path.GetDirectoryName(videoPath) ?? "";

                    //GlobalFFOptions.Current.TemporaryFilesFolder
                    //var destinationPathExecp = Path.Combine(Path.GetTempPath(), $"{Path.GetFileNameWithoutExtension(videoPath)}{FileExtension.Mp4}");


                    //VideoCombine.mustClearPath.Add(destinationPathExecp);

                    // 配置 FFmpeg 参数
                    //var options = new FFMpegArgumentOptions()
                    //    .WithVideoCodec("libx264") // 指定支持 CRF 的编码器
                    //    .WithConstantRateFactor(23) // 内置方法设置 CRF
                    //    .WithAudioCodec("aac")      // 音频编码器
                    //    .WithFastStart();           // 流媒体优化


                    FFMpegArguments
                        .FromFileInput(videoPath)
                        .OutputToFile(destinationPath, true, o => o
                            .WithVideoCodec("libx264") // 设置视频编码器
                            .WithAudioCodec("aac") // 设置音频编码器
                            .WithAudioSamplingRate(44100)
                            .WithAudioBitrate(128000)
                            .WithConstantRateFactor(23) // 设置质量调整参数
                            .WithCustomArgument("-vf fps=30") // 强制指定帧率（例如 30fps）
                            .WithFastStart()
                            //.WithCustomArgument("-movflags +faststart") // 确保 moov atom 正确写入
                            //.CopyChannel()
                            //.WithBitStreamFilter(Channel.Video, Filter.H264_Mp4ToAnnexB)
                            .ForceFormat(VideoType.Ts)
                        )
                        //.NotifyOnOutput(Console.WriteLine) // 打印 FFmpeg 详细日志
                        .ProcessSynchronously(true);
                    //FFMpeg.Convert(destinationPathExecp, destinationPath, VideoType.Ts);

                }
                catch (Exception e)
                {
                    LogUtils.Error($"{videoPath} 转换失败", ex);
                    LogUtils.Error($"{videoPath} 转换再次失败", e);
                }

            }

            return destinationPath;
        }

        public static string GetLargeFileMD5(string filePath)
        {
            using var md5 = MD5.Create();
            using var stream = File.OpenRead(filePath);

            byte[] buffer = new byte[8192]; // 8KB 缓冲区
            int bytesRead;
            long totalBytesRead = 0;

            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                md5.TransformBlock(buffer, 0, bytesRead, null, 0);
                totalBytesRead += bytesRead;
                // 可在此添加进度显示：Console.WriteLine($"已读取 {totalBytesRead / 1024 / 1024}MB");
            }

            md5.TransformFinalBlock(buffer, 0, 0);
            return BitConverter.ToString(value: md5.Hash).Replace("-", "").ToLowerInvariant();
        }
    }
}
