using BDU.Logic;
using BDU.Models;
using BDU.Tools;
using BDU.Windows;
using ATS_DBContext;
using MaterialDesignThemes.Wpf;
using Microsoft.Win32;
using Newtonsoft.Json;
using PropertyChanged;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TSMasterCAN;
using static BDU.Models.ParameterModel;
using Path = System.IO.Path;

namespace BDU.Views
{
    /// <summary>
    /// ToolBar.xaml 的交互逻辑
    /// </summary>
    [AddINotifyPropertyChangedInterface]
    public partial class ToolBar : UserControl
    {
        public static ToolBar Instance { get; private set; }
        public string CurSubProgramPath { get; set; }
        public bool SingleStep = false;
        public string RunState { get; set; } = "运行";

        public PackIconKind RunIcon { get; set; } = PackIconKind.Play;

        public bool? IsStop { get; set; } = null;

        
        public bool IsTerminate { get; set; } = false;

        public bool? CanReport => IsStop == false; // 是否可以导出报告
        public bool IsAdmin => MainWindow.Instance.User.Role > 0;

        public bool IsDebug => MainWindow.Instance.User.UserName == "开发者" && MainWindow.Instance.User.UserAccount == "Developer";

        private Task? currentExecutionTask;

        public ToolBar()
        {
            Instance = this;
            InitializeComponent();
            DataContext = this;

            // 监听主窗口属性变化，特别是 Title 变化
            if (MainWindow.Instance != null)
            {
                MainWindow.Instance.PropertyChanged += (s, e) =>
                {
                    if (e.PropertyName == nameof(MainWindow.IsInSubProgramMode) ||
                        e.PropertyName == "Title") // 监听 Title 变化
                    {
                        OnPropertyChanged(nameof(IsInSubProgramMode));
                        OnPropertyChanged(nameof(CurrentPathDisplay));
                    }
                };
            }

            this.Loaded += (s, e) => LoadDefaultProgramIfExists();
        }
        private void LoadDefaultProgramIfExists()
        {
            try
            {
                if (File.Exists(SystemConfig.Instance.DefaultSubProgramFilePath))
                {
                    string json = File.ReadAllText(SystemConfig.Instance.DefaultSubProgramFilePath);
                    var tmp = JsonConvert.DeserializeObject<ProgramModel>(json);
                    if (tmp != null)
                    {
                        MainWindow.Instance.Program = tmp;
                        InitParameter(tmp);
                        InitDevice(tmp);
                    }
                    else
                    {
                        MainWindow.Instance.Program = new();
                    }
                    MainWindow.Instance.CurrentFilePath = SystemConfig.Instance.DefaultSubProgramFilePath;
                    Log.Success($"已打开文件: {SystemConfig.Instance.DefaultSubProgramFilePath}");
                }
            }
            catch (Exception ex)
            {
                Log.Error($"默认程序：{SystemConfig.Instance.DefaultSubProgramFilePath} 文件打开失败：{ex.Message}");
            }
        }
        #region 辅助方法

        private void InitDevice(ProgramModel program)
        {
            if (program.Devices != null && program.Devices.Count > 0)
            {
                foreach (DeviceModel device in program.Devices)
                {
                    _ = DeviceConnect.InitAndConnectDevice(program, device);
                }
            }
            foreach (var step in program.StepCollection)
            {
                if (step.SubProgram != null)
                {
                    InitDevice(step.SubProgram);
                }
            }
        }

        private void InitParameter(ProgramModel program)
        {
            if (program.Parameters != null && program.Parameters.Count > 0)
            {
                foreach (var parameter in program.Parameters)
                {
                    if (parameter.Type!.BaseType == typeof(Enum))
                    {
                        parameter.Value = Enum.Parse(parameter.Type, parameter.Value!.ToString()!);
                    }
                }
            }
            foreach (var step in program.StepCollection)
            {
                if (step.SubProgram != null)
                {
                    InitDevice(step.SubProgram);
                }
            }
        }

        private void SaveProgramToFile(string filePath)
        {
            try
            {
                var tmp = ClearDeviceParameterValue(MainWindow.Instance.Program);
                string json = JsonConvert.SerializeObject(tmp, Formatting.Indented);
                File.WriteAllText(filePath, json);
                Log.Success($"程序已保存: {filePath}");
            }
            catch (Exception ex)
            {
                Log.Error($"保存文件失败: {ex.Message}");
            }
        }

        private ProgramModel ClearUnnecessaryParameterValue(ProgramModel program)
        {
            var tmp = new ProgramModel(program);
            foreach (var step in tmp.StepCollection)
            {
                if (step.Method != null)
                {
                    foreach (var para in step.Method.Parameters)
                    {
                        if (para.VariableID != null && para.Category == ParameterCategory.Output)
                        {
                            para.Value = null;
                            tmp.Parameters.First(x => x.ID == para.VariableID)!.Value = null;
                        }
                    }
                }
                else if (step.SubProgram != null)
                {
                    var subTmp = ClearUnnecessaryParameterValue(step.SubProgram);
                    step.SubProgram = subTmp;
                }
            }
            return tmp;
        }

        private ProgramModel ClearDeviceParameterValue(ProgramModel program)
        {
            var tmp = new ProgramModel(program);
            foreach (var device in tmp.Devices)
            {
                tmp.Parameters.Remove(tmp.Parameters.First(x => x.ID == device.ParameterID));
            }
            foreach (var step in tmp.StepCollection)
            {
                if (step.SubProgram != null)
                {
                    step.SubProgram = ClearDeviceParameterValue(step.SubProgram);
                }
            }
            return tmp;
        }

        #endregion

        private void File_New_Click(object sender, RoutedEventArgs e)
        {
            MainWindow.Instance.Program = new();
            MainWindow.Instance.CurrentFilePath = "";
        }
        private void Set_DefaultProgram_Click(object sender, RoutedEventArgs e)
        {
            SystemConfig.Instance.DefaultSubProgramFilePath = CurSubProgramPath;
            SystemConfig.Instance.SaveToFile();
        }
        private void File_Open_Click(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new OpenFileDialog
            {
                Filter = "ATS程序文件|*.ats|所有文件|*.*",
                Title = "打开程序文件"
            };

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    CurSubProgramPath = openFileDialog.FileName;
                    string json = File.ReadAllText(openFileDialog.FileName);
                    var tmp = JsonConvert.DeserializeObject<ProgramModel>(json);
                    if (tmp != null)
                    {
                        MainWindow.Instance.Program = tmp;
                        MainWindow.Instance.Title = Path.GetFileName(openFileDialog.FileName).Split(".ats")[0];
                        InitParameter(tmp);
                        InitDevice(tmp);
                    }
                    else
                    {
                        MainWindow.Instance.Program = new();
                    }
                    MainWindow.Instance.SelectedStep = null;
                    MainWindow.Instance.CurrentFilePath = openFileDialog.FileName;
                    Log.Success($"已打开文件: {openFileDialog.FileName}");
                }
                catch (Exception ex)
                {
                    Log.Error($"程序文件打开失败：{ex.Message}");
                }
            }
        }

        private void File_Save_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(MainWindow.Instance.CurrentFilePath))
            {
                File_SaveAsOther_Click(sender, e);
            }
            else
            {
                SaveProgramToFile(MainWindow.Instance.CurrentFilePath);
            }
        }

        private void File_SaveAsOther_Click(object sender, RoutedEventArgs e)
        {
            var saveFileDialog = new SaveFileDialog
            {
                Filter = "ATS程序文件|*.ats|所有文件|*.*",
                Title = "另存为",
                FileName = "NewProgram.ats"
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                MainWindow.Instance.CurrentFilePath = saveFileDialog.FileName;
                SaveProgramToFile(MainWindow.Instance.CurrentFilePath);
            }
        }

        private async void ProgramRun_Click(object sender, RoutedEventArgs e)
        {
            if (RunState == "运行")
            {
                SingleStep = false;
                Log.Info($"用户 [ {MainWindow.Instance.User.UserName} ] 点击 [ 运行 ] ");
                // 清空报告列表
                ReportModelList.ReportList = new();
                RunState = "暂停";
                RunIcon = PackIconKind.Pause;
                if (IsStop == null)
                {
                    IsStop = false;
                    currentExecutionTask = StepRunning.ExecuteSteps(MainWindow.Instance.Program, cancellationToken: StepRunning.stepCTS.Token);
                    await currentExecutionTask;
                    RunState = "运行";
                    RunIcon = PackIconKind.Play;
                    IsStop = null;                   
                }
                else if (IsStop == true)
                {
                    IsStop = false;
                }
            }
            else
            {
                Log.Info($"用户 [ {MainWindow.Instance.User.UserName} ] 点击 [ 暂停 ] ");
                IsStop = true;
                RunState = "运行";
                RunIcon = PackIconKind.Play;
            }
        }
        private async void SingleStepExecution_Click(object sender, RoutedEventArgs e)
        {
            if (RunState == "运行")
            {
                SingleStep = true;
                Log.Info($"用户 [ {MainWindow.Instance.User.UserName} ] 点击 [ 单步执行 ] ");
                RunState = "暂停";
                RunIcon = PackIconKind.Pause;
                if (IsStop == null)
                {
                    IsStop = false;
                    currentExecutionTask = StepRunning.ExecuteSteps(MainWindow.Instance.Program, cancellationToken: StepRunning.stepCTS.Token);
                    await currentExecutionTask;
                    RunState = "运行";
                    RunIcon = PackIconKind.Play;
                    IsStop = null;
                }
                else if (IsStop == true)
                {
                    IsStop = false;
                }
            }


        }
        private void Terminate_Click(object sender, RoutedEventArgs e)
        {
            if (IsStop == false)
            {
                Log.Info($"用户 [ {MainWindow.Instance.User.UserName} ] 点击 [ 停止 ] ");
                IsTerminate = true;
                IsStop = null;
                RunState = "运行";
                RunIcon = PackIconKind.Play;
                StepRunning.stepCTS.Cancel();
            }
        }

        private void Reset_Click(object sender, RoutedEventArgs e)
        {
            Log.Info($"用户 [ {MainWindow.Instance.User.UserName} ] 点击 [ 复位 ] ");
            IsTerminate = false;
            currentExecutionTask = null;
            StepRunning.stepCTS = new();
            StepRunning.ResetAllStepStatus(MainWindow.Instance.Program);
        }

        //导出按钮
        private void Report_Click(object sender, RoutedEventArgs e)
        {
            Log.Info($"用户 [ {MainWindow.Instance.User.UserName} ] 点击 [ 导出报告 ] ");
            if (ReportModelList.ReportList != null && ReportModelList.ReportList.Count > 0)
            {
                //生成csv报告文件
                GenerateCsvReport();
            }
            else
            {
                Log.Warning("当前无报告可导出");
                MessageBox.Show("当前无报告可导出", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }


        private void ChannelMapping_Click(object sender, RoutedEventArgs e)
        {
            var re = CAN.ShowChannelMappingWindow(true);
            if (re != 0)
            {
                var msg = CAN.GetErrorDescription(re);
                Log.Error($"同星通道映射界面打开失败：{msg}");
            }
        }

        private void TestDataInfo_Click(object sender, RoutedEventArgs e)
        {
            new TestDataInfomationWindow().Show();
        }

        private void SystemConfig_Click(object sender, RoutedEventArgs e)
        {
            new SystemConfigWindow().Show();
        }

        Task? DebugAutoRunTask;
        CancellationTokenSource DebugAutoRunTaskCT;
        private void Debug_AutoRun_Click(object sender, RoutedEventArgs e)
        {
            if (MainWindow.Instance.Program.StepCollection.Count == 0) return;
            if (DebugAutoRunTask == null)
            {
                DebugAutoRunTaskCT = new();
                try
                {
                    DebugAutoRunTask = Task.Run(async () =>
                    {
                        while (true)
                        {
                            DebugAutoRunTaskCT.Token.ThrowIfCancellationRequested();
                            await StepRunning.ExecuteSteps(MainWindow.Instance.Program, cancellationToken: DebugAutoRunTaskCT.Token);
                        }
                    });
                }
                catch (OperationCanceledException)
                {

                }
            }
            else
            {
                DebugAutoRunTaskCT.Cancel();
                DebugAutoRunTask = null;
            }
        }

        private async void Debug_ClearDataBase_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show($"确定执行删除操作？", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.Yes)
            {
                using ATS_DB db = new();
                db.TestData.RemoveRange(db.TestData);
                await db.SaveChangesAsync();
            }
        }

        private void CAN_DatabaseConnect_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Title = "请选择 DBC 文件",
                Filter = "DBC 文件 (*.dbc)|*.dbc",
                //InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Multiselect = false
            };

            if (openFileDialog.ShowDialog() == true)
            {
                var re = CAN.LoadDBC(openFileDialog.FileName, [0, 1, 2, 3], out var DataBaseID);
                if (re != 0)
                {
                    Log.Error("CAN数据库加载失败：" + CAN.GetErrorDescription(re));
                }
                else
                {
                    Log.Success("CAN数据库加载成功");
                }
            }
        }

        private bool isConnect = true;
        private void Connect_DisConnect_Click(object sender, RoutedEventArgs e)
        {
            if (isConnect)
            {
                var res = CAN.DisConnect();
                if (res == 0)
                {
                    Log.Success($"CAN卡断开连接成功,返回值:{res}");
                    isConnect = false;
                }
                else
                {
                    Log.Error($"CAN卡断开连接失败,返回值:{res}");
                }
                
                
            }
            else
            {
                var res = CAN.Connect();
                if (res == 0)
                {
                    Log.Success($"CAN卡连接成功,返回值:{res}");
                    isConnect = true;
                }
                else
                {
                    Log.Error($"CAN卡连接失败,返回值:{res}");
                }
            }
        }
        private void GenerateCsvReport()
        {
            try
            {
                // 生成文件名（包含当前时间戳）
                string fileName = $"Report_{DateTime.Now:yyyyMMdd_HHmmss}.csv";
                string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Reports", fileName);

                // 确保 Reports 目录存在
                string directory = Path.GetDirectoryName(filePath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                // 写入 CSV 文件
                using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
                {
                    // 写入 CSV 头部（新增"所属子程序"列）
                    writer.WriteLine("步骤序号,步骤名称,所属子程序,备注,执行人,执行时间,是否通过,结果");

                    var allPASS = true;
                    // 写入数据行
                    foreach (var report in ReportModelList.ReportList)
                    {
                        string stepIndex = report.stepModel?.Index.ToString() ?? "";
                        string stepName = EscapeCsvField(report.stepModel?.Name ?? "");
                        string subProgramPath = EscapeCsvField(report.SubProgramPath); // 新增列
                        string stepRemark = EscapeCsvField(report.stepModel?.Description ?? "");
                        string user = EscapeCsvField(report.User);
                        string executeTime = report.ExcuteTime?.ToString("yyyy-MM-dd HH:mm:ss");
                        string isPass = report.IsPass.ToString(); // 根据你的 IsPass 枚举定义，可能需要调整
                        if (isPass == "FAIL") allPASS = false;
                        string result = EscapeCsvField(report.Result ?? "");

                        writer.WriteLine($"{stepIndex},{stepName},{subProgramPath},{stepRemark},{user},{executeTime},{isPass},{result}");
                    }
                    // 写入报告总结果
                    writer.WriteLine("");
                    writer.WriteLine($"测试总结果,,,,,,{(allPASS ? "PASS" : "FAIL")},");

                }

                Log.Success($"报告导出成功，路径：{filePath}");
                MessageBox.Show($"报告导出成功！\n文件路径：{filePath}", "导出成功", MessageBoxButton.OK, MessageBoxImage.Information);

                // 可选：打开文件所在目录
                System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{filePath}\"");
            }
            catch (Exception ex)
            {
                Log.Error($"导出报告失败：{ex.Message}");
                MessageBox.Show($"导出报告失败：{ex.Message}", "导出失败", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 转义 CSV 字段中的特殊字符（逗号、双引号、换行符等）
        /// </summary>
        /// <param name="field">原始字段值</param>
        /// <returns>转义后的字段值</returns>
        private string EscapeCsvField(string field)
        {
            if (string.IsNullOrEmpty(field))
                return "";

            // 如果字段包含逗号、双引号或换行符，则用双引号包围，并将双引号转义为两个双引号
            if (field.Contains(",") || field.Contains("\"") || field.Contains("\n") || field.Contains("\r"))
            {
                return "\"" + field.Replace("\"", "\"\"") + "\"";
            }

            return field;
        }

        private void CAN_CatchConfig_Click(object sender, RoutedEventArgs e)
        {
            new CANCatchSingalView().Show();
        }






        // 添加 IsInSubProgramMode 依赖属性或普通属性
        // 如果 MainWindow.Instance.IsInSubProgramMode 是普通属性，可以用普通属性
        public bool IsInSubProgramMode => MainWindow.Instance?.IsInSubProgramMode ?? false;



        // 修改 CurrentPathDisplay 属性，直接从 MainWindow 获取 Title
        public string CurrentPathDisplay
        {
            get
            {
                // 直接使用 MainWindow 的 Title，它已经在 MainWindow 中被正确管理
                return MainWindow.Instance?.Title ?? "ATS";
            }
            set
            {
                if (MainWindow.Instance != null)
                {
                    value = MainWindow.Instance.Title;
                }
            }
        }


        private void NavigateBack_Click(object sender, RoutedEventArgs e)
        {
            MainWindow.Instance?.ExitSubProgramMode();
        }

        private void DeviceManage_Click(object sender, RoutedEventArgs e)
        {
            new DeviceManageWindow().Show();
        }
    }
}
