using LiveCharts;
using NEIntelligentControl2.Models;
using NEIntelligentControl2.Models.Datas;
using NEIntelligentControl2.Models.Messages;
using NEIntelligentControl2.Models.PV;
using NEIntelligentControl2.Service.Windturbine;
using NEIntelligentControl2.Views.Infos;
using System;
using System.Collections.Generic;
using System.Configuration;
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.Shapes;

namespace NEIntelligentControl2.Windows.PV
{

    /// <summary>
    /// SUN2000光伏机型的详细页面
    /// </summary>
    public partial class SUN2000InfoWindow : Window
    {
        public static readonly DependencyProperty IsForwardSortProperty = DependencyProperty.Register("IsForwardSort", typeof(bool), typeof(SUN2000InfoWindow));

        /// <summary>
        /// 是否活跃
        /// </summary>
        private bool _IsActived;
        /// <summary>
        /// 数据请求url
        /// </summary>
        private string _Url = "";
        /// <summary>
        /// 所有UniformCode
        /// </summary>
        private string _Codes = "";

        private List<SUN2000Info> _SUN2000Infos;

        /// <summary>
        /// 光伏逆变器ID
        /// </summary>
        public string PVId { get; set; }
        /// <summary>
        /// 是否正向排序
        /// </summary>
        public bool IsForwardSort { get => (bool)GetValue(IsForwardSortProperty); set => SetValue(IsForwardSortProperty, value); }
        private WEBHelper _WEBHelper;
        private InfoManager _InfoService;
        public SUN2000InfoWindow(WEBHelper web, InfoManager iss)
        {
            InitializeComponent();
            _WEBHelper = web;
            _InfoService = iss;
            Init();
        }

        private void Init()
        {
            _SUN2000Infos = _InfoService.GetSUN2000Infos();
            if (_SUN2000Infos == null)
            {
                return;
            }
            try
            {
#if (DEBUG)
                _Url = ConfigurationManager.AppSettings["DataServicePathDebug"];
#else
                _Url = ConfigurationManager.AppSettings["ServicePath"];
#endif
            }
            catch (Exception ex)
            {
                Console.WriteLine("读取配置文件[DataServicePath]出错!", ex);
            }
            // 初始化UniformCode
            InitTags();

            _IsActived = true;
            Task.Factory.StartNew(RefreshData, TaskCreationOptions.LongRunning);
            Task.Run(InitHistoryData);
        }

        /// <summary>
        /// 初始化历史数据
        /// </summary>
        private void InitHistoryData()
        {
            DateTime de = DateTime.Now;
            DateTime ds = DateTime.Parse("06:00");
            List<List<TsData>> ls = new List<List<TsData>>();
            foreach (var v in _SUN2000Infos)
            {
                var url = $"{_Url}/ts/history/snap?thingType=windturbine&thingId={PVId}&uniformCode={v.I.Code}&startTs={ds.GetTimeSpan()}&endTs={de.GetTimeSpan()}&interval=60";
                var vs = _WEBHelper.HttpGetJSON<List<TsData>>(url);
                if (vs == null || vs.Count <= 0)
                {
                    continue;
                }
                if (v.ΔI == 0)
                {
                    v.ΔI = GetΔI(vs);
                }
                ls.Add(vs);
            }
            List<TsData> Δtss = GetDataSum(ls);

            AddAxisX(Δtss);
            SetCahrValues(Δtss);
        }

        /// <summary>
        /// 添加横坐标
        /// </summary>
        private void AddAxisX(List<TsData> val)
        {
            List<string> vs = new List<string>();
            DateTime dtStand = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
            foreach (var v in val)
            {
                DateTime dt = dtStand.AddMilliseconds(v.Ts);
                vs.Add(dt.ToShortTimeString());
            }
            if (vs.Count <= 0) return;
            Dispatcher.Invoke(() => _ChartAxisX.Labels = vs);
        }

        /// <summary>
        /// 设置图表数据 
        /// </summary>
        private void SetCahrValues(List<TsData> values)
        {
            ChartValues<double> cv = new ChartValues<double>();
            foreach (var v in values)
            {
                cv.Add(v.Value);
            }
            Dispatcher.Invoke(() =>
            {
                _LineChartI.Values = cv;
            });
        }

        /// <summary>
        /// 获取历史值的和的变化值
        /// </summary>
        private List<TsData> GetDataSum(List<List<TsData>> vs)
        {
            List<TsData> ls = new List<TsData>();
            double oi = 0;
            for (int i = 0; i < vs[0].Count; ++i)
            {
                double d = 0;
                long ts = 0;
                foreach (var v in vs)
                {
                    if (v.Count <= i)
                    {
                        continue;
                    }
                    d += v[i].Value;
                    ts = v[i].Ts;
                }
                if (d == 0)
                {
                    continue;
                }
                if (oi != 0)
                {
                    ls.Add(new TsData() { Ts = ts, Value = Math.Abs(d - oi) });
                }
                oi = d;
            }
            return ls;
        }

        /// <summary>
        /// 从历史数据中获取电流变化值
        /// </summary>
        private double GetΔI(List<TsData> vs)
        {
            if (vs == null || vs.Count <= 0) return 0;
            double s = vs[vs.Count - 1].Value;
            for (int i = vs.Count - 2; i >= 0; --i)
            {
                if (vs[i].Value == s)
                {
                    continue;
                }
                return Math.Abs(s - vs[i].Value);
            }
            return 0;
        }

        private void InitTags()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var v in _SUN2000Infos)
            {
                sb.Append(v.I.Code).Append(',').Append(v.V.Code).Append(',');
                SUN2000InfoTag st = new SUN2000InfoTag() { Info = v };
                _SPMain.Children.Add(st);
            }
            _Codes = sb.ToString();
        }

        private async void RefreshData()
        {
            var url = $"{_Url}/ts/latest?thingType=windturbine&thingId={PVId}&uniformCodes={_Codes}";
            while (_IsActived)
            {
                try
                {
                    var vs = _WEBHelper.HttpGetJSON<Dictionary<string, TsData>>(url);
                    Dispatcher.Invoke(() =>
                    {
                        foreach (var v in _SUN2000Infos)
                        {
                            v.UpdateValue(vs);
                        }
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
                await Task.Delay(1000);
            }
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => this.DragMove();

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _IsActived = false;
            this.Close();
        }

        internal static void Show(InverterInfoWindow iiw)
        {
            if (iiw == null || iiw.Block == null)
            {
                return;
            }
            SUN2000InfoWindow siw = App.ServiceProvider.GetService(typeof(SUN2000InfoWindow)) as SUN2000InfoWindow;
            siw.PVId = iiw.Block.Id;
            siw.Owner = iiw;
            siw.ShowDialog();
        }

        /// <summary>
        /// 排序
        /// </summary>
        private void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            List<SUN2000InfoTag> ls = _SPMain.Children.OfType<SUN2000InfoTag>().ToList();
            if ((((FrameworkElement)sender).Tag as string) == "p")
            {
                _SPP.Visibility = Visibility.Visible;
                _SPI.Visibility = Visibility.Collapsed;
                ls.Sort((x, y) =>
                {
                    if (x.P == y.P) return 0;
                    int i = 0;
                    if (x.P > y.P)
                    {
                        i = 1;
                    }
                    else
                    {
                        i = -1;
                    }
                    return IsForwardSort ? i : -i;
                });
            }
            else
            {
                _SPI.Visibility = Visibility.Visible;
                _SPP.Visibility = Visibility.Collapsed;
                ls.Sort((x, y) =>
                {
                    if (x.I == y.I) return 0;
                    int i = 0;
                    if (x.I > y.I)
                    {
                        i = 1;
                    }
                    else
                    {
                        i = -1;
                    }
                    return IsForwardSort ? i : -i;
                });
            }
            IsForwardSort = !IsForwardSort;
            foreach (var v in ls)
            {
                _SPMain.Children.Remove(v);
                _SPMain.Children.Add(v);
            }
        }
    }
}