using NEIntelligentControl2.Models.Datas;
using NEIntelligentControl2.Models.Windturbine;
using NEIntelligentControl2.Service.Windturbine;
using NEIntelligentControl2.Views.Windturbine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;
using System.Runtime.CompilerServices;
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.Shapes;

namespace NEIntelligentControl2.Windows
{
    /// <summary>
    /// 参数对比页面
    /// </summary>
    public partial class ParameterComparisonWindow : Window
    {
        public List<WindturbineInfo> WindturbineInfos { get; set; }

        private List<ParameterInfo> _ParameterInfos;
        private InfoManager _InfoManager;
        private List<CheckBox> _TitleCheckBoxs;
        private List<ExpandoObject> _Datas;
        private List<string> _Names;

        private Dictionary<string, List<ParameterInfo>> _WindturbineParameterInfos;
        private Dictionary<string, List<ComparisonTagInfo>> _TagInfos;
        private Dictionary<string, List<ComparisonTagInfo>> _NameTagInfos;
        private List<ComparisonTagInfo> _ComparisonTagInfos;

        private bool _IsActive;
        public ParameterComparisonWindow(InfoManager im)
        {
            InitializeComponent();
            _InfoManager = im;
        }

        /// <summary>
        /// 初始化信息
        /// </summary>
        private void InitInfos()
        {
            if (WindturbineInfos == null) return;
            var value = WindturbineInfos;
            _ParameterInfos = new List<ParameterInfo>();
            _TitleCheckBoxs = new List<CheckBox>();
            _Names = new List<string>();
            if (value == null || value.Count <= 0) return;
            HashSet<string> keys = new HashSet<string>();
            foreach (var v in value)
            {
                var id = $"{v.StationId}{v.ModelId}";
                if (keys.Contains(id)) continue;
                keys.Add(id);
                var pis = _InfoManager.GetParameterInfos(v.StationId, v.ModelId);
                foreach (var pi in pis)
                {
                    if (_Names.Contains(pi.Name)) continue;
                    _Names.Add(pi.Name);
                    CheckBox cb = new CheckBox() { Content = pi.Name, Foreground = new SolidColorBrush(Colors.WhiteSmoke), Margin = new Thickness(3), FontSize = 14, IsChecked = true, Tag = pi.Name };
                    System.Windows.Shell.WindowChrome.SetIsHitTestVisibleInChrome(cb, true);
                    cb.Click += CheckBox_Click;
                    _TitleCheckBoxs.Add(cb);
                    _WPTitle.Children.Add(cb);
                }
            }
            InitWindturbine();
        }

        private void InitWindturbine()
        {
            _WindturbineParameterInfos = new Dictionary<string, List<ParameterInfo>>();
            _TagInfos = new Dictionary<string, List<ComparisonTagInfo>>();
            _NameTagInfos = new Dictionary<string, List<ComparisonTagInfo>>();
            _ComparisonTagInfos = new List<ComparisonTagInfo>();
            _Datas = new List<ExpandoObject>();
            foreach (var v in WindturbineInfos)
            {
                dynamic item = new ExpandoObject();
                item.Name = v.Name;
                item.WindturbineId = v.WindturbineId;
                ComparisonInfo ci = new ComparisonInfo() { Name = v.Name };
                item.ComparisonInfo = ci;
                IDictionary<string, object> itemc = item as IDictionary<string, object>;
                var pis = _InfoManager.GetParameterInfos(v.StationId, v.ModelId);
                _WindturbineParameterInfos.Add(v.WindturbineId, pis);
                Dictionary<string, int> indexs = new Dictionary<string, int>();
                foreach (var pi in pis)
                {
                    int index = _Names.IndexOf(pi.Name);
                    if (index < 0) continue;
                    var vname = $"Val_{index}";
                    if (!itemc.ContainsKey(vname))
                    {
                        var cif = new ComparisonTagInfo() { Code = pi.Code, Name = pi.Name };
                        _ComparisonTagInfos.Add(cif);
                        if (!_TagInfos.ContainsKey(v.WindturbineId))
                        {
                            _TagInfos.Add(v.WindturbineId, new List<ComparisonTagInfo>());
                        }
                        if (!_NameTagInfos.ContainsKey(pi.Name))
                        {
                            _NameTagInfos.Add(pi.Name, new List<ComparisonTagInfo>());
                        }
                        _TagInfos[v.WindturbineId].Add(cif);
                        _NameTagInfos[pi.Name].Add(cif);
                        itemc.Add(vname, cif);
                        indexs.Add(pi.Code, index);
                    }
                }
                ci.Infos = indexs;
                _Datas.Add(item);
            }
            var dgis = FindResource("DataGridItemStyle") as DataTemplate;
            int ind = 0;
            foreach (var v in _Names)
            {
                //var dg = new DataGridTemplateColumn() { Header = v, CellTemplate = dgis, MinWidth = 100 };


                var dg = new DataGridTemplateColumn() { MinWidth = 100, IsReadOnly = true };
                dg.Header = new ComparisonHeader() { Header = v, OnClick = HeaderClick };
                Binding binding = new Binding()
                {
                    Path = new PropertyPath($"Val_{ind}")
                };

                DataTemplate dt = new DataTemplate();

                var item = new FrameworkElementFactory(typeof(ComparisonTag));
                item.SetBinding(ComparisonTag.InfoProperty, binding);
                dt.VisualTree = item;
                dg.CellTemplate = dt;


                _DGMain.Columns.Add(dg);

                ++ind;
            }
            _DGMain.ItemsSource = _Datas;
        }

        private void HeaderClick(string obj)
        {
            var vs = _ComparisonTagInfos.Where(i => i.Name == obj).ToList();
            foreach(var v in vs)
            {
                v.IsShowProgress = !v.IsShowProgress;
            }
        }

        public static void ShowWindow(List<Models.Windturbine.WindturbineInfo> ws)
        {
            ParameterComparisonWindow pcw = App.ServiceProvider.GetService(typeof(ParameterComparisonWindow)) as ParameterComparisonWindow;
            pcw.WindturbineInfos = ws;
            pcw.Owner = App.Current.MainWindow;
            pcw.ShowDialog();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            switch (((Control)sender).Tag)
            {
                case "close":
                    this.Close();
                    break;
            }
        }

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            var tag = ((Control)sender).Tag as string;
            if (tag == "all")
            {
                var isChecked = (sender as CheckBox).IsChecked;
                foreach (var v in _TitleCheckBoxs)
                {
                    v.IsChecked = isChecked;
                }
            }
            var ls = _TitleCheckBoxs.Where(c => c.IsChecked == true).Select(c => c.Tag as string).ToList();
            foreach (var v in _DGMain.Columns)
            {
                string s = v.Header as string;
                if (s == null)
                {
                    s = (v.Header as ComparisonHeader)?.Header;
                }
                if (s == "风机名称" || ls.Contains(s))
                {
                    v.Visibility = Visibility.Visible;
                }
                else
                {
                    v.Visibility = Visibility.Collapsed;
                }
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitInfos();
            _IsActive = true;
            Task.Run(RefreshData);
        }

        private async void RefreshData()
        {
            while (_IsActive)
            {
                try
                {
                    foreach (var v in _WindturbineParameterInfos)
                    {
                        var ucs = v.Value.Select(x => x.Code).ToArray();
                        var vv = _InfoManager.GetPointDatas(v.Key, ucs);

                        UpdateData(v.Key, vv); ;
                    }
                    InitMaxValue();
                }
                catch { }

                await Task.Delay(1500);
            }
        }

        private void InitMaxValue()
        {
            foreach(var v in _NameTagInfos)
            {
                var max = v.Value.Max(i => i.Value);
                foreach(var vv in v.Value)
                {
                    vv.MaxValue = max;
                }
            }
        }

        private void UpdateData(string key, Dictionary<string, TsData> vv)
        {
            if (!_TagInfos.ContainsKey(key)) return;
            var vs = _TagInfos[key];
            foreach (var v in vs)
            {
                if (vv.ContainsKey(v.Code))
                {
                    v.Value = Math.Round(vv[v.Code].Value, 2);
                }
            }
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            _IsActive = false;
        }
    }

    class ComparisonInfo
    {
        public string Name { get; set; }
        public Dictionary<string, int> Infos { get; set; }
    }

    public class ComparisonTagInfo : INotifyPropertyChanged
    {
        private double value;
        public double Value { get => value; set { this.value = value; Progress = Value / MaxValue; OnPropertyChanged(); } }
        private double maxValue;
        public double MaxValue { get => maxValue; set { maxValue = value; Progress = Value / MaxValue; OnPropertyChanged(); } }
        private bool isShowProgress;
        public bool IsShowProgress { get=> isShowProgress; set { isShowProgress = value; OnPropertyChanged(); } }
        public string Code { get; set; }
        private double progress;
        public double Progress { get => progress; set { progress = value; OnPropertyChanged(); } }

        public string Name { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}
