using BOB.Services;
using BOB.Singleton;
using Common.PubEvent;
using Common.PubEvents;
using Logger;
using Microsoft.Win32;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Legends;
using OxyPlot.Series;
using Prism.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;

namespace BOB.ViewModels
{
    public class MonitorViewModel : BindableBase, INavigationAware
    {
        #region 属性
        private PlotModel _CurveModel=new();

        public PlotModel CurveModel
        {
            get => _CurveModel;
            set => SetProperty(ref _CurveModel, value);
        }
        private Dictionary<string, LineSeries> _SeriesDic = new ();

        public Dictionary<string,LineSeries> SeriesDic
        {
            get => _SeriesDic;
            set => SetProperty(ref _SeriesDic, value);
        }
        private string _FilePath;

        public string FilePath
        {
            get => _FilePath;
            set => SetProperty(ref _FilePath, value);
        }
        private string _SelectCurve;

        public string SelectCurve
        {
            get => _SelectCurve;
            set => SetProperty(ref _SelectCurve, value);
        }
        private string _SelectDeleteCurve;

        public string SelectDeleteCurve
        {
            get => _SelectDeleteCurve;
            set => SetProperty(ref _SelectDeleteCurve, value);
        }
        private string _SelectedSaveDays;

        public string SelectedSaveDays
        {
            get => _SelectedSaveDays;
            set => SetProperty(ref _SelectedSaveDays, value);
        }
        //private ObservableCollection<string> _CurSingleList=new();

        public ObservableCollection<string> CurSingleList
        {
            get => SystemConfig.Instance.CurSingleList;
            set
            {
                if (SystemConfig.Instance.CurSingleList != value)
                {
                    SystemConfig.Instance.CurSingleList = value;
                    RaisePropertyChanged();
                }
            }
        }
        private ObservableCollection<string> _DeviceSingleList = new();

        public ObservableCollection<string> DeviceSingleList
        {
            get => _DeviceSingleList;
            set => SetProperty(ref _DeviceSingleList, value);
        }
        #endregion
        #region 命令
        public ICommand ResetViewCommand { get; set; }
        public ICommand AddSignalCommand { get; set; }
        public ICommand RemoveSignalCommand { get; set; }
        public ICommand ChanegPathCommand { get; set; }
        public ICommand SaveCommand { get; set; }

        #endregion
        private IEventAggregator _eventAggregator;
        private IDialogService _dialogService;
        private static Random _random = new Random();
        private DispatcherTimer _refreshTimer;
        private Devices _devices { get; set; }
        private readonly IProgress<(string name, double value)> _progress;
        public MonitorViewModel(IEventAggregator eventAggregator, IDialogService dialogService, IContainerProvider containerProvider )
        {
            _dialogService = dialogService;
            _eventAggregator = eventAggregator;
            _devices = containerProvider.Resolve<Devices>();
            ResetViewCommand = new DelegateCommand(ResetView);
            AddSignalCommand = new DelegateCommand<string>(AddSignal);
            RemoveSignalCommand = new DelegateCommand(RemoveSignal);
            ChanegPathCommand = new DelegateCommand(ChanegPath);
            SaveCommand = new DelegateCommand(Save);
            _eventAggregator.GetEvent<CurveDataEvent>().Subscribe(OnCurveDataReceived);
            _progress = new Progress<(string name, double value)>(UpdateCurveOnUI);
            InitData();
        }
        private void UpdateCurveOnUI((string name, double value) update)
        {
            var (signalName, value) = update;

            if (!SeriesDic.TryGetValue(signalName, out var line))
                return;

            line.Points.Add(DateTimeAxis.CreateDataPoint(DateTime.Now, value));
        }

        private async void OnCurveDataReceived((string device, Dictionary<string, double> data) tuple)
        {
            await Task.Run(() =>
            {
                var (device, data) = tuple;
                foreach (var item in data)
                {
                    string propname = item.Key;
                    double value = item.Value;
                    string signalName = device + "." + propname;

                    if (CurSingleList.Contains(signalName))
                    {
                        // 通过 Progress 安全更新 UI
                        _progress.Report((signalName, value));
                    }
                }
            });
        }


        private void InitData()
        {
            SelectedSaveDays=SystemConfig.Instance.SaveDay.ToString();
            FilePath= SystemConfig.Instance.DBSavePath;
            foreach (var _PollingRead in _devices.PollingReadDic)
            {
                string deviceName = _PollingRead.Key;
                PollingRead pollingRead = _PollingRead.Value;

                var props = pollingRead.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                           .Where(p => p.PropertyType == typeof(double));

                foreach (var prop in props)
                {
                    DeviceSingleList.Add(deviceName + "." + prop.Name);
                }
            }
             foreach(var curve in CurSingleList)
               {
                   AddSignal(curve);
               }
            InitCurveModel();
            InitTimer();
        }
        private void InitCurveModel()
        {
            CurveModel.Axes.Clear();

            var timeAxis = new DateTimeAxis
            {
                Position = AxisPosition.Bottom,
                StringFormat = "HH:mm:ss",
                Title = "时间",
                IntervalType = DateTimeIntervalType.Seconds
            };
            CurveModel.Axes.Add(timeAxis);

            var valueAxis = new LinearAxis
            {
                Position = AxisPosition.Left,
                Title = "数值"
            };
            CurveModel.Axes.Add(valueAxis);
        }

        private void InitTimer()
        {
            _refreshTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(1)
            };
            _refreshTimer.Tick += (s, e) =>
            {
                CurveModel.InvalidatePlot(true);
            };
            _refreshTimer.Start();
        }


        private OxyColor GetRandomColor()
        {
            // 生成随机的红色、绿色、蓝色分量，范围是 0 到 255
            byte r = (byte)_random.Next(0, 256);
            byte g = (byte)_random.Next(0, 256);
            byte b = (byte)_random.Next(0, 256);

            // 返回一个随机的颜色
            return OxyColor.FromRgb(r, g, b);
        }

        private void AddSignal(string Curve="")
        {
            try
            {
                if (Curve == null)
                {
                    if (_SeriesDic.ContainsKey(SelectCurve))
                    {
                        return;
                    }
                    else
                    {
                        var sineSignal = new LineSeries
                        {
                            Title = SelectCurve,
                            MarkerType = MarkerType.Circle,
                            StrokeThickness = 2,
                            Color = GetRandomColor()
                        };
                        CurveModel.Series.Add(sineSignal);
                        CurveModel.Legends.Add(new Legend
                        {
                            LegendPosition = LegendPosition.TopCenter,   // 图表顶部中间
                            LegendOrientation = LegendOrientation.Horizontal, // 横向排列
                            LegendPlacement = LegendPlacement.Inside,    // 放在图上面
                            LegendBorderThickness = 0,                    // 去掉边框，可选
                            LegendBackground = OxyColors.WhiteSmoke      // 背景色，可选
                        });

                        SeriesDic.Add(SelectCurve, sineSignal);
                        CurSingleList.Add(SelectCurve);
                        SystemConfig.Instance.SaveToFile();
                        CurveModel.InvalidatePlot(true);
                    }
              
                }
                else
                {
                    var sineSignal = new LineSeries
                    {
                        Title = Curve,
                        MarkerType = MarkerType.Circle,
                        StrokeThickness = 2,
                        Color = GetRandomColor()
                    };
                    CurveModel.Series.Add(sineSignal);
                    CurveModel.Legends.Add(new Legend
                    {
                        LegendPosition = LegendPosition.TopCenter,   // 图表顶部中间
                        LegendOrientation = LegendOrientation.Horizontal, // 横向排列
                        LegendPlacement = LegendPlacement.Inside,    // 放在图上面
                        LegendBorderThickness = 0,                    // 去掉边框，可选
                        LegendBackground = OxyColors.WhiteSmoke      // 背景色，可选
                    });

                    SeriesDic.Add(Curve, sineSignal);
                    CurveModel.InvalidatePlot(true);
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.ErrorWithNotify("添加曲线失败", ex.StackTrace);
            }
        }
        private void RemoveSignal()
        {
            try
            {
                if (_SeriesDic.ContainsKey(SelectDeleteCurve))
                {
                    var signalToRemove = _SeriesDic[SelectDeleteCurve];
                    _SeriesDic.Remove(SelectDeleteCurve);
                    CurveModel.Series.Remove(signalToRemove);
                    CurSingleList.Remove(SelectDeleteCurve);
                    SystemConfig.Instance.SaveToFile();
                    CurveModel.InvalidatePlot(true);
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.ErrorWithNotify("删除曲线失败",ex.StackTrace);
            }
        }
        private void Save()
        {
            SelectedSaveDays = SelectedSaveDays ?? "30";
            if (int.TryParse(SelectedSaveDays, out int saveDays))
            {
                if (saveDays > 0 && saveDays <= 30)
                {
                    Console.WriteLine($"保存天数: {saveDays}");
                }
                else
                {
                    //_dialogService.ShowDialog("请输入1到30之间的有效天数。", "无效输入");
                }
            }
            else
            {
                //_dialogService.ShowDialog("请输入有效的数字。", "无效输入");
            }
        }


        public void ChanegPath()
        {
            var openFileDialog = new OpenFileDialog
            {
                CheckFileExists = false,  
                CheckPathExists = true,   
                FileName = "Folder",      
                ValidateNames = false,  
                Filter = "All files (*.*)|*.*"
            };
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (openFileDialog.ShowDialog() == true)
            {
                FilePath = System.IO.Path.GetDirectoryName(openFileDialog.FileName);
                SystemConfig.Instance.DBSavePath = FilePath;
                SystemConfig.Instance.SaveToFile();
            }
           
        }

        private void ResetView()
        {
            CurveModel.ResetAllAxes();
            CurveModel.InvalidatePlot(true);
        }
        #region 导航
        public void OnNavigatedTo(NavigationContext navigationContext)
        {

        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }
        #endregion
    }
}
