using Panuon.WPF.UI;
using SWRIS.Core;
using SWRIS.Dtos;
using SWRIS.Enums;
using SWRIS.Events;
using SWRIS.Extensions;
using SWRIS.Models;
using SWRIS.Models.ViewModel;
using SWRIS.Pages;
using SWRIS.Repository;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Speech.Synthesis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace SWRIS
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : WindowX, IComponentConnector
    {
        private readonly SpeechSynthesizer speech;
        public MainViewModel MainView { get; set; }

        private readonly IRecordRepository _recordRepository;
        private readonly IAlarmRepository _alarmRepository;
        public MainWindow()
        {
            InitializeComponent();
            _recordRepository = new RecordRepository();
            _alarmRepository = new AlarmRepository();
            speech = new SpeechSynthesizer()
            {
                Rate = 1,
                Volume = 100
            };
            MainView = new MainViewModel()
            {
                AppName = App.Config.AppName,
                Version = App.Config.Version,
                Copyright = App.Config.Copyright,
                SwitchInstances = App.Config.SwitchInstances
            };
            Application.Current.MainWindow = this;
            App.TcpServer.ClientConnected += TcpServer_ClientConnected;
            App.TcpServer.ClientDisconnected += TcpServer_ClientDisconnected;
            App.TcpServer.AlarmDataReceived += TcpServer_AlarmDataReceived;
            App.TcpServer.DetectionDataReceived += TcpServer_DetectionDataReceived;
            App.TcpServer.RealTimeDataReceived += TcpServer_RealTimeDataReceived;
            App.TcpServer.FaultDataReceived += TcpServer_FaultDataReceived;
            App.TcpServer.DetectionRawDataReceived += TcpServer_DetectionRawDataReceived;
            App.TcpServer.DetectionRawDataResultReceived += TcpServer_DetectionRawDataResultReceived;
            App.TcpServer.DetectionStatusResultReceived += TcpServer_DetectionStatusResultReceived;
            App.TcpServer.DebugMessageReceived += TcpServer_DebugMessageReceived;
            App.TcpServer.HeartbeatReceived += TcpServer_HeartbeatReceived;
            App.TcpServer.UpgradedRequestResultReceived += TcpServer_UpgradedRequestResultReceived;
            App.Calibration.ConnectionStateChanged += Calibration_ConnectionStateChanged;
            App.Calibration.LimitStateChanged += Calibration_LimitStateChanged;


            App.TcpServer.Start();

            DataContext = MainView;
        }



        /// <summary>
        /// 接收心跳数据
        /// </summary>
        private void TcpServer_HeartbeatReceived(object sender, HeartbeatReceviedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                equipmentData.IsHeartbeatReceived = true;
            }
        }
        /// <summary>
        /// 接收调试信息
        /// </summary>
        private void TcpServer_DebugMessageReceived(object sender, DebugMessageReceivedEventArgs e)
        {
            if (e.IpAddress.IsNullOrEmpty() && e.SerialNo.IsNullOrEmpty())
            {
                DebugMessageShow(e.Message);
            }
            else
            {
                DebugMessageShow(e.Message, e.IpAddress, e.SerialNo);
            }
        }
        public void DebugMessageShow(string message, string ipAddress, string serialNo)
        {
            if (App.Config.ShowDebugMessage)
            {
                var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == ipAddress || (serialNo != null && c.SerialNo == serialNo));
                if (equipmentData != null)
                {
                    equipmentData.DebugMessage.DateTime = DateTime.Now;
                    equipmentData.DebugMessage.Message = message;
                }
            }
        }
        public void DebugMessageShow(string message)
        {
            if (App.Config.ShowDebugMessage)
            {
                MainView.DebugMessage.DateTime = DateTime.Now;
                MainView.DebugMessage.Message = message;
            }
        }
        /// <summary>
        /// 标定限位状态更改
        /// </summary>
        private void Calibration_LimitStateChanged(object sender, LimitData limitData)
        {
            foreach (var equipment in App.DataCenter.Equipments)
            {
                foreach (var limit in equipment.Limits)
                {
                    if (limit.Name == limitData.Name && limit.IsEnable)
                    {
                        if (limitData.State == LimitState.AtLimit)
                        {
                            limit.State = LimitState.AtLimit;
                            // 当前运行状态添加预标定状态
                            equipment.RunningStatus |= RunningStatus.PreCalibration;
                            if (App.TcpServer.SendRealTimeAbsolutePositionData((float)limitData.Position, equipment.SerialNo, equipment.ClientSocket))
                            {
                                DebugMessageShow($"{limitData.Name}标定成功", equipment.IpAddress, equipment.SerialNo);
                            }
                        }
                        else if (limitData.State == LimitState.NotInLimit)
                        {
                            limit.State = LimitState.NotInLimit;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 标定模块连接状态更改
        /// </summary>
        private void Calibration_ConnectionStateChanged(object sender, bool isConnect)
        {
            foreach (var equipment in App.DataCenter.Equipments)
            {
                foreach (var limit in equipment.Limits)
                {
                    if (isConnect)
                    {
                        if (limit.State == LimitState.Offline)
                        {
                            limit.State = LimitState.NotInLimit;
                        }
                    }
                    else
                    {
                        if (limit.State != LimitState.Offline)
                        {
                            limit.State = LimitState.Offline;
                        }
                    }
                }
            }

        }
        /// <summary>
        /// 接收检测状态开关结果
        /// </summary>
        private void TcpServer_DetectionStatusResultReceived(object sender, DetectionStatusResultReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                if (equipmentData.RunningStatus.HasFlag(RunningStatus.PreStop))
                {
                    equipmentData.RunningStatus = RunningStatus.Stopped;
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        NoticeBox.Show("自动检测停止", "通知", MessageBoxIcon.Warning, true, 3000);
                    });
                }
                else if (equipmentData.RunningStatus.HasFlag(RunningStatus.PreRunning))
                {
                    equipmentData.RunningStatus = RunningStatus.TemporalNormal;
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        NoticeBox.Show("自动检测恢复", "通知", MessageBoxIcon.Success, true, 3000);
                    });
                }
                else if (equipmentData.RunningStatus.HasFlag(RunningStatus.PreCalibration))
                {
                    equipmentData.RunningStatus = RunningStatus.TemporalNormal;
                }
            }
        }
        /// <summary>
        /// 接收故障数据
        /// </summary>
        private void TcpServer_FaultDataReceived(object sender, FaultDataReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            equipmentData?.Faults.Add(e.FaultData);
        }
        /// <summary>
        /// 接收实时数据
        /// </summary>
        private void TcpServer_RealTimeDataReceived(object sender, RealTimeDataReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                equipmentData.Speed = Math.Round(e.RealTimeData.Speed * 60, 2);
                equipmentData.Position = e.RealTimeData.Position;
                equipmentData.RunningStatus = e.RealTimeData.Status;
                equipmentData.AbsolutePosition = e.RealTimeData.AbsolutePosition;
                equipmentData.LiftHeight = (equipmentData.RopeLength - equipmentData.AbsolutePosition) / equipmentData.LiftHightRatio;
                equipmentData.Direction = equipmentData.Speed > 0 ? DirectionState.Forward :
                    (equipmentData.Speed == 0f ? DirectionState.Stoped : DirectionState.Reverse);
                equipmentData.AddSpeedData(equipmentData.Speed);
            }
        }
        /// <summary>
        /// 客户端连接成功
        /// </summary>
        private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
        {
            var equipment = App.Config.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipment == null)
            {
                LogHelper.Error($"未找到设备，IP地址：{e.IpAddress}");
                return;
            }
            var server = (TcpServerFrame)sender;
            server.SendTurnLiveStreamData(true, equipment.SerialNo, e.ClientSocket);
            Thread.Sleep(20);
            server.SendSetClockData(DateTime.Now.DateTimeToTimestamp(), equipment.SerialNo, e.ClientSocket);
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                equipmentData.IsConnect = true;
                equipmentData.ClientSocket = e.ClientSocket;
                if (equipmentData.RunningStatus != RunningStatus.TemporalNormal)
                {
                    equipmentData.RunningStatus |= RunningStatus.TemporalNormal;
                }
            }
        }
        /// <summary>
        /// 客户端连接断开
        /// </summary>
        private void TcpServer_ClientDisconnected(object sender, ClientDisconnectedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                equipmentData.IsConnect = false;
                equipmentData.ClientSocket = null;
                equipmentData.Speed = 0;
                equipmentData.AbsolutePosition = 0;
                equipmentData.Position = 0;
                equipmentData.Direction = DirectionState.Stoped;
            }
        }
        /// <summary>
        /// 接收检测结果
        /// </summary>
        private void TcpServer_DetectionDataReceived(object sender, DetectionDataReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                e.DetectionData.DetectionNo = equipmentData.DetectionNo;
                equipmentData.DetectionData = e.DetectionData;
            }
        }
        /// <summary>
        /// 接检测原始数据结果
        /// </summary>
        private void TcpServer_DetectionRawDataResultReceived(object sender, DetectionRawDataResultReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                // 处理检测原始结果数据
                if (e.DetectionRawResultData.Code == 0)
                {
                    if (equipmentData.DetectionData != null)
                    {
                        equipmentData.DetectionData.RawResultData = e.DetectionRawResultData;
                    }
                }
                else
                {
                    LogHelper.Error($"获取检测原始数据失败，错误码：{e.DetectionRawResultData.Code}");
                }
            }
        }
        /// <summary>
        /// 接受检测结果原始数据
        /// </summary>
        private async void TcpServer_DetectionRawDataReceived(object sender, DetectionRawDataReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null)
            {
                if (equipmentData.DisableAlarm)
                {
                    DebugMessageShow($"获取检测结果原始数据结束", equipmentData.IpAddress, equipmentData.SerialNo);
                    return;
                }
                await Task.Run(() =>
                {
                    if (equipmentData.DetectionData != null && equipmentData.DetectionData.RawResultData != null)
                    {
                        DebugMessageShow($"数据接收：{e.DetectionRawData.PacketNumber}/{e.DetectionRawData.TotalPackets}", equipmentData.IpAddress, equipmentData.SerialNo);
                        if (e.DetectionRawData.PacketNumber == 1)
                        {
                            equipmentData.DetectionData.RawDataReceiving = true;
                            equipmentData.DetectionData.RawData = new MemoryStream();
                            equipmentData.DetectionData.RawData.Write(e.DetectionRawData.Data, 0, e.DetectionRawData.Data.Length);
                        }
                        else if (e.DetectionRawData.PacketNumber <= e.DetectionRawData.TotalPackets)
                        {
                            // 添加原始数据到检测数据中
                            equipmentData.DetectionData.RawData.Write(e.DetectionRawData.Data, 0, e.DetectionRawData.Data.Length);
                            // 如果是最后一包数据，处理检测数据
                            if (e.DetectionRawData.PacketNumber == e.DetectionRawData.TotalPackets)
                            {
                                // 生成数据文件路径
                                (string absolutePath, string relativePath) = DatFileHandler.GetDatFilePath(equipmentData.SerialNo);
                                // 处理检测数据逻辑
                                var record = new RecordDto
                                {
                                    RopeName = equipmentData.RopeName,
                                    RopeNumber = equipmentData.RopeNumber,
                                    StartPoint = equipmentData.DetectionData.StartPoint,
                                    EndPoint = equipmentData.DetectionData.EndPoint,
                                    DetectedSpeed = equipmentData.DetectionData.DetectedSpeed,
                                    DetectionLength = equipmentData.DetectionData.DetectionLength,
                                    StartTime = equipmentData.DetectionData.StartTime.TimestampToDateTime(),
                                    EndTime = equipmentData.DetectionData.EndTime.TimestampToDateTime(),
                                    SensorCount = equipmentData.DetectionData.RawResultData.SensorCount,
                                    SamplingStep = equipmentData.DetectionData.RawResultData.SamplingStep,
                                    DataFilePath = relativePath,
                                    InUseSensors = string.Join(",", equipmentData.InUseSensor)
                                };
                                foreach (var damage in equipmentData.DetectionData.Damages)
                                {
                                    var alarmCount = _alarmRepository.AddAlarm(new AlarmDataModel
                                    {
                                        DamageLevel = damage.DamageLevel,
                                        DamagePosition = damage.DamagePoint,
                                        DamageValue = damage.DamageValue,
                                        RopeNumber = equipmentData.RopeNumber
                                    }, AlarmSourceType.Detection, App.Config.DamageExtent);
                                    if (alarmCount >= App.Config.AlarmValidCount)
                                    {
                                        record.Damages.Add(new DamageDto
                                        {
                                            DamageLevel = damage.DamageLevel,
                                            DamagePoint = damage.DamagePoint,
                                            DamageValue = damage.DamageValue,
                                        });
                                        record.DamageCount++;
                                        //纠正健康度 以客户端上传的损伤数据 重新计算
                                        if ((int)record.RiskLevel < (int)damage.DamageLevel)
                                        {
                                            record.RiskLevel = (RiskLevel)damage.DamageLevel;
                                        }
                                    }
                                }
                                equipmentData.RiskLevel = record.RiskLevel;
                                if (record.DamageCount > 0)
                                {
                                    int? recordId = _recordRepository.CreateRecord(record);
                                    if (recordId.HasValue)
                                    {
                                        record.Id = recordId.Value;
                                        AddRecordToPageRecords(record);
                                        if (!DatFileHandler.CreateDatFile(absolutePath, equipmentData.DetectionData.RawData))
                                        {
                                            LogHelper.Error($"创建检测数据文件失败，路径：{absolutePath}");
                                        }
                                        DebugMessageShow($"检测数据记录成功", equipmentData.IpAddress, equipmentData.SerialNo);
                                        if ((int)record.RiskLevel >= (int)App.Config.SoundRiskLevel)
                                        {
                                            Application.Current.Dispatcher.Invoke(() =>
                                            {
                                                speech.SpeakAsync($"{equipmentData.RopeName}，检测到{record.DamageCount}处损伤");
                                            });
                                        }
                                    }
                                    else
                                    {
                                        LogHelper.Error("检测数据记录失败");
                                    }
                                }
                                else
                                {
                                    DebugMessageShow($"检测完成，未发现损伤，本次检测不做记录。", equipmentData.IpAddress, equipmentData.SerialNo);
                                }
                                equipmentData.DetectionData.RawDataReceiving = false;
                            }
                        }
                    }
                });
            }
        }
        /// <summary>
        /// 接收报警数据
        /// </summary>
        private void TcpServer_AlarmDataReceived(object sender, AlarmDataReceivedEventArgs e)
        {
            var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
            if (equipmentData != null && equipmentData.IsSpeedStable && !equipmentData.DisableAlarm)
            {
                Dispatcher.InvokeAsync(() =>
                {
                    e.AlarmData.RopeNumber = equipmentData.RopeNumber;
                    var alarmCount = _alarmRepository.AddAlarm(e.AlarmData, AlarmSourceType.RealTime, App.Config.DamageExtent);
                    if (alarmCount >= App.Config.AlarmValidCount)
                    {
                        equipmentData.AddAlarm(e.AlarmData);
                    }
                });
            }
        }
        private void TcpServer_UpgradedRequestResultReceived(object sender, UpgradedResultReceivedEventArgs e)
        {
            Dispatcher.InvokeAsync(async () =>
            {
                if (e.Code == 0)
                {
                    await Task.Delay(2000);
                    string url = $"http://192.168.1.200"; // 替换为您的网页地址
                    Extensions.Tools.OpenUrl(url);
                }
            });
        }
        public void AddRecordToPageRecords(RecordDto record)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (main_frame.Content is Page currentPage && currentPage != null)
                {
                    var simpleRecord = record.ToSimpleRecordDto();
                    switch (currentPage.Title)
                    {
                        case "OneRopePage":
                            if (currentPage.DataContext is OneRopeViewModel oneRopeView)
                            {
                                oneRopeView.AddRecord(simpleRecord);
                            }
                            break;
                        case "TwoRopesPage":
                            if (currentPage.DataContext is TwoRopesViewModel twoRopesView)
                            {
                                twoRopesView.AddRecord(simpleRecord);
                            }
                            break;
                        case "ThreeRopesPage":
                            if (currentPage.DataContext is ThreeRopesViewModel threeRopesView)
                            {
                                threeRopesView.AddRecord(simpleRecord);
                            }
                            break;
                        case "FourRopesPage":
                            if (currentPage.DataContext is FourRopesViewModel fourRopesView)
                            {
                                fourRopesView.AddRecord(simpleRecord);
                            }
                            break;
                    }
                }
            });
        }
        private void WindowX_Loaded(object sender, RoutedEventArgs e)
        {
            NavigateToPage("Home");
        }
        public void NavigatePage(Uri uri)
        {
            main_frame.NavigationService.Navigate(uri);
        }
        private void NavigateToPage(object pageName)
        {
            switch (pageName)
            {
                case "Home":
                    MainView.CurrentPage = "Home";
                    int equipmentCount = App.Config.Equipments.Count;
                    switch (equipmentCount)
                    {
                        case 1:
                            main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/OneRopePage.xaml", uriKind: UriKind.Relative));
                            break;
                        case 2:
                            main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/TwoRopesPage.xaml", uriKind: UriKind.Relative));
                            break;
                        case 3:
                            main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/ThreeRopesPage.xaml", uriKind: UriKind.Relative));
                            break;
                        case 4:
                            main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/FourRopesPage.xaml", uriKind: UriKind.Relative));
                            break;
                    }
                    break;
                case "Record":
                    MainView.CurrentPage = "Record";
                    main_frame.NavigationService.Navigate(new Uri($"Pages/RecordPage.xaml", uriKind: UriKind.Relative));
                    break;
            }
        }
        private void Menu_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sender is TextBlock menuItem)
            {
                CleanNavigation(main_frame);
                NavigateToPage(menuItem?.Tag);
            }
        }
        private void CleanNavigation(Frame frame)
        {
            while (frame.CanGoBack)
                frame.RemoveBackEntry();
        }
        private void StackPanel_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                Left = 0;
                Top = 0;
            }
        }
        private void Setting_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            SettingDialog settingDialog = new SettingDialog();
            if (settingDialog.ShowDialog(true) == true)
            {
                if (settingDialog.IsAutoStart)
                {
                    App.RestartApplication();
                }
            }
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            App.TcpServer?.Dispose();
            speech?.Dispose();
        }

        private void Minimize_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        private void Close_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var result = MessageBoxX.Show(this, "退出后将无法进行实时检测，是否确认退出程序？", "警告",
                MessageBoxButton.YesNo,
                MessageBoxIcon.Warning, DefaultButton.YesOK);
            if (result == MessageBoxResult.Yes)
            {
                Close();
            }
        }

        private void SwitchToInstance_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sender is Border instanceBorder && instanceBorder.Tag != null)
            {
                App.SwitchToExistingInstance(instanceBorder.Tag.ToString());
            }
        }
    }
}
