using FFMpegCore;
using FFMpegCore.Enums;
using Microsoft.Expression.Drawing.Core;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Threading;
using VideoConcat.Common.Tools;
using VideoConcat.Models;
using VideoConcat.Services.Video;
using static VideoConcat.Models.VideoModel;
using MessageBox = System.Windows.MessageBox;

namespace VideoConcat.ViewModels
{
    public class ExtractWindowViewModel
    {
        private ExtractWindowModel _extractWindowModel;

        public List<ConcatVideo> ConcatVideos { get; set; } = [];

        public ExtractWindowModel ExtractWindowModel
        {
            get { return _extractWindowModel; }
            set
            {
                _extractWindowModel = value;
            }
        }



        public ExtractWindowViewModel()
        {
            ExtractWindowModel = new ExtractWindowModel
            {
                CanExtractFrame = false,
                CanModify = false,
                IsStart = false,
                IsCanOperate = true,

                BtnOpenFolderCommand = new Command()
                {
                    DoExcue = obj =>
                    {
                        System.Windows.Forms.FolderBrowserDialog folderBrowserDialog = new();
                        if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            ExtractWindowModel.FolderPath = folderBrowserDialog.SelectedPath;
                            LogUtils.Info($"获取视频文件夹,视频路径:{ExtractWindowModel.FolderPath}");
                            ListFolder();
                        }
                    }

                },

                BtnStartVideoConcatCommand = new Command()
                {
                    DoExcue = obj =>
                    {
                        // 在后台任务中执行异步操作
                        Task.Run(async () =>
                        {
                            int extractCount = ExtractWindowModel.ExtractCount;
                            if (extractCount <= 0)
                            {
                                ExtractWindowModel.Dispatcher.Invoke(() =>
                                {
                                    MessageBox.Show("请输入有效的生成个数（大于0）！", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                                });
                                return;
                            }

                            ExtractWindowModel.Dispatcher.Invoke(() =>
                            {
                                ExtractWindowModel.HelpInfo = $"开始处理，每个视频将生成 {extractCount} 个抽帧视频...";
                                ExtractWindowModel.IsStart = true;
                                ExtractWindowModel.IsCanOperate = false;
                            });

                            SemaphoreSlim semaphore = new(10); // 限制并发数量

                            List<Task> _tasks = [];
                            int totalTasks = ExtractWindowModel.videos.Length * extractCount;
                            int completedTasks = 0;
                            System.Collections.Concurrent.ConcurrentBag<string> errorMessages = new(); // 收集错误信息

                            // 对每个视频生成指定数量的抽帧视频
                            foreach (var video in ExtractWindowModel.videos)
                            {
                                for (int i = 1; i <= extractCount; i++)
                                {
                                    int currentIndex = i; // 闭包变量
                                    string currentVideo = video; // 闭包变量
                                    
                                    await semaphore.WaitAsync();
                                    var _task = Task.Run(async () =>
                                    {
                                        try
                                        {
                                            string _tmpPath = Path.GetDirectoryName(currentVideo) ?? "";
                                            if (string.IsNullOrEmpty(_tmpPath))
                                            {
                                                LogUtils.Error($"无法获取视频目录：{currentVideo}");
                                                Interlocked.Increment(ref completedTasks);
                                                ExtractWindowModel.Dispatcher.Invoke(() =>
                                                {
                                                    ExtractWindowModel.HelpInfo = $"处理中... ({completedTasks}/{totalTasks})";
                                                });
                                                return;
                                            }

                                            string originalFileName = Path.GetFileNameWithoutExtension(currentVideo);
                                            string extension = Path.GetExtension(currentVideo);
                                            
                                            // 生成唯一的文件名：原文件名_序号.扩展名
                                            string _tmpFileName = $"{originalFileName}_{currentIndex:D4}{extension}";

                                            string outPath = Path.Combine(_tmpPath, "out");
                                            LogUtils.Info($"准备创建输出目录：{outPath}");
                                            
                                            try
                                            {
                                                if (!Directory.Exists(outPath))
                                                {
                                                    Directory.CreateDirectory(outPath);
                                                    LogUtils.Info($"已创建输出目录：{outPath}");
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                LogUtils.Error($"创建输出目录失败：{outPath}", ex);
                                                Interlocked.Increment(ref completedTasks);
                                                ExtractWindowModel.Dispatcher.Invoke(() =>
                                                {
                                                    ExtractWindowModel.HelpInfo = $"处理中... ({completedTasks}/{totalTasks})";
                                                });
                                                return;
                                            }

                                            string outputPath = Path.Combine(outPath, _tmpFileName);
                                            LogUtils.Info($"开始抽帧：输入={currentVideo}, 输出={outputPath}");
                                            
                                            // 如果文件已存在，跳过
                                            if (File.Exists(outputPath))
                                            {
                                                LogUtils.Info($"文件已存在，跳过：{outputPath}");
                                                Interlocked.Increment(ref completedTasks);
                                                ExtractWindowModel.Dispatcher.Invoke(() =>
                                                {
                                                    ExtractWindowModel.HelpInfo = $"处理中... ({completedTasks}/{totalTasks})";
                                                });
                                                return;
                                            }

                                            // 先检查视频时长
                                            try
                                            {
                                                var mediaInfo = await FFProbe.AnalyseAsync(currentVideo);
                                                double totalDuration = mediaInfo.Duration.TotalSeconds;
                                                
                                                if (totalDuration < 20)
                                                {
                                                    string videoName = Path.GetFileName(currentVideo);
                                                    string errorMsg = $"视频时长太短：{videoName}（{totalDuration:F2}秒），无法抽帧（需要至少20秒）";
                                                    LogUtils.Error(errorMsg);
                                                    errorMessages.Add(errorMsg);
                                                    
                                                    Interlocked.Increment(ref completedTasks);
                                                    ExtractWindowModel.Dispatcher.Invoke(() =>
                                                    {
                                                        ExtractWindowModel.HelpInfo = $"处理中... ({completedTasks}/{totalTasks})";
                                                    });
                                                    return;
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                LogUtils.Error($"检查视频时长失败：{currentVideo}", ex);
                                                // 继续处理，让 RemoveFrameRandomeAsync 来处理错误
                                            }

                                            bool success = await VideoProcess.RemoveFrameRandomeAsync(currentVideo, outputPath);
                                            
                                            // 再次检查文件是否存在
                                            if (File.Exists(outputPath))
                                            {
                                                FileInfo fileInfo = new FileInfo(outputPath);
                                                LogUtils.Info($"抽帧成功：{currentVideo} -> {outputPath}, 文件大小={fileInfo.Length / 1024 / 1024}MB");
                                            }
                                            else if (success)
                                            {
                                                LogUtils.Warn($"抽帧返回成功但文件不存在：{outputPath}");
                                            }
                                            else
                                            {
                                                string videoName = Path.GetFileName(currentVideo);
                                                string errorMsg = $"抽帧失败：{videoName}";
                                                LogUtils.Error($"{errorMsg} -> {outputPath}");
                                                errorMessages.Add(errorMsg);
                                            }
                                            
                                            // 更新完成计数
                                            Interlocked.Increment(ref completedTasks);
                                            ExtractWindowModel.Dispatcher.Invoke(() =>
                                            {
                                                ExtractWindowModel.HelpInfo = $"处理中... ({completedTasks}/{totalTasks})";
                                            });
                                        }
                                        catch (Exception ex)
                                        {
                                            string videoName = Path.GetFileName(currentVideo);
                                            string errorMsg = $"抽帧异常：{videoName} (第{currentIndex}个) - {ex.Message}";
                                            LogUtils.Error($"抽帧失败：{currentVideo} (第{currentIndex}个)", ex);
                                            errorMessages.Add(errorMsg);
                                            Interlocked.Increment(ref completedTasks);
                                            ExtractWindowModel.Dispatcher.Invoke(() =>
                                            {
                                                ExtractWindowModel.HelpInfo = $"处理中... ({completedTasks}/{totalTasks})";
                                            });
                                        }
                                        finally
                                        {
                                            semaphore.Release();
                                        }
                                    });
                                    _tasks.Add(_task);
                                }
                            }

                            await Task.WhenAll(_tasks);
                            
                            // 统计实际生成的文件数量
                            int actualFileCount = 0;
                            string outputDir = "";
                            if (ExtractWindowModel.videos.Length > 0)
                            {
                                string firstVideo = ExtractWindowModel.videos[0];
                                string videoDir = Path.GetDirectoryName(firstVideo) ?? "";
                                outputDir = Path.Combine(videoDir, "out");
                                
                                if (Directory.Exists(outputDir))
                                {
                                    actualFileCount = Directory.GetFiles(outputDir, "*.mp4").Length;
                                    LogUtils.Info($"输出目录 {outputDir} 中共有 {actualFileCount} 个视频文件");
                                }
                            }
                            
                            // 构建最终信息
                            string summaryInfo = $"全部完成! 共处理 {completedTasks} 个任务，实际生成 {actualFileCount} 个视频文件\n输出目录：{outputDir}";
                            
                            ExtractWindowModel.Dispatcher.Invoke(() =>
                            {
                                // 如果有错误信息，显示汇总
                                if (errorMessages.Count > 0)
                                {
                                    string errorSummary = string.Join("\n", errorMessages);
                                    ExtractWindowModel.HelpInfo = $"{summaryInfo}\n\n错误信息（共{errorMessages.Count}个）：\n{errorSummary}";
                                }
                                else
                                {
                                    ExtractWindowModel.HelpInfo = summaryInfo;
                                }
                                ExtractWindowModel.IsStart = false;
                                ExtractWindowModel.IsCanOperate = true;
                            });
                            LogUtils.Info($"抽帧处理完成，共处理 {completedTasks} 个任务，实际生成 {actualFileCount} 个视频文件，输出目录：{outputDir}");
                        });
                    }
                },

                BtnStartVideoModifyCommand = new Command()
                {
                    DoExcue = obj =>
                    {
                        ExtractWindowModel.HelpInfo = "";


                        SemaphoreSlim semaphore = new(10); // Limit to 3 threads

                        List<Task> _tasks = [];

                        ExtractWindowModel.videos.ForEach(async (video) =>
                        {
                            await semaphore.WaitAsync(); // Wait when more than 3 threads are running
                            var _task = Task.Run(async () =>
                            {
                                try
                                {
                                    // 实例化并调用
                                    var remover = new VideoProcess();
                                    // 删除4秒处的帧（需根据实际帧位置调整）
                                    string _tmpPath = Path.GetDirectoryName(video) ?? "";
                                    string _tmpFileName = $"{(new Random()).Next(10000, 99999)}{Path.GetFileName(video)}";

                                    string outPath = Path.Combine(_tmpPath, "out");
                                    if (!Path.Exists(outPath))
                                    {
                                        Directory.CreateDirectory(outPath);
                                    }

                                    VideoProcess.ModifyByMetadata(video, $"{_tmpPath}\\out\\modify{_tmpFileName}");
                                }
                                finally
                                {
                                    semaphore.Release(); // Work is done, signal to semaphore that more work is possible
                                }
                            });
                            _tasks.Add(_task);
                        });

                        Task.WhenAll(_tasks).ContinueWith((task) =>
                        {
                            ExtractWindowModel.HelpInfo = "全部完成!";
                        });
                    }
                }
            };
        }

        private void ListFolder()
        {
            DirectoryInfo dir = new(ExtractWindowModel.FolderPath);
            try
            {
                DirectoryInfo dirD = dir as DirectoryInfo;

                //获取文件夹下所有视频文件

                ExtractWindowModel.videos = Directory.GetFiles(dirD.FullName, "*.mp4");
                ExtractWindowModel.SetCanStart();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }
    }
}
