using FLY.OBJComponents.IService;
using FLY.Weight2.IService;
using FLY.Weight2.Server.Model;
using GalaSoft.MvvmLight.Command;
using Misc;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Navigation;
using Unity;

namespace FLY.Weight2.UI.Client
{
    /// <summary>
    /// Page_Flow.xaml 的交互逻辑
    /// </summary>
    public partial class PgFlowTable : Page
    {
        IUnityContainer container;
        IWeightSystemService weightSystemService;
        PgFlowTableVm viewModel;

        public PgFlowTable()
        {
            InitializeComponent();
        }

        [InjectionMethod]
        public void Init(
            IUnityContainer container,
            IWeightSystemService weightSystemService)
        {
            this.container = container;
            this.weightSystemService = weightSystemService;

            //界面........................................

            InitDataGrid();

            viewModel = container.Resolve<PgFlowTableVm>();
            this.DataContext = viewModel;
            stackpanel_weight.DataContext = this.weightSystemService;
        }

        void InitDataGrid()
        {
            DataGridTextColumn c = new DataGridTextColumn()
            {
                CanUserSort = false,
                CanUserReorder = false,

                Header = "时间",
                Binding = new Binding(nameof(Lc_Flow.Time)) { StringFormat = "{0:MM/dd HH:mm}" }
            };
            gridFlows.Columns.Add(c);

            c = new DataGridTextColumn()
            {
                CanUserSort = false,
                CanUserReorder = false,
                Header = "总流量 kg/h",
                Binding = new Binding(nameof(Lc_Flow.Total)) { StringFormat = "{0:F1}" }
            };
            gridFlows.Columns.Add(c);

            for (int i = 0; i < weightSystemService.ItemsCnt; i++)
            {
                var weight = weightSystemService.Items[i];

                string name = $"{weight.Number}层";
                c = new DataGridTextColumn()
                {
                    CanUserSort = false,
                    CanUserReorder = false,
                    Header = name + "流量 kg/h",
                    Binding = new Binding($"{nameof(Lc_Flow.Items)}[{i}].{nameof(Lc_FlowItem.Flow)}") { StringFormat = "{0:F1}" }
                };
                gridFlows.Columns.Add(c);

                c = new DataGridTextColumn()
                {
                    CanUserSort = false,
                    CanUserReorder = false,
                    Header = name + "比例 %",
                    Binding = new Binding($"{nameof(Lc_Flow.Items)}[{i}].{nameof(Lc_FlowItem.ScrewPDisp)}") { StringFormat = "{0:F1}" }
                };
                gridFlows.Columns.Add(c);

                c = new DataGridTextColumn()
                {
                    CanUserSort = false,
                    CanUserReorder = false,
                    Header = name + "频率 Hz",
                    Binding = new Binding($"{nameof(Lc_Flow.Items)}[{i}].{nameof(Lc_FlowItem.ScrewMotorFreq)}") { StringFormat = "{0:F1}" }
                };
                gridFlows.Columns.Add(c);
            }
        }
    }
    public class PgFlowTableVm : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 当前页面最后一行Id
        /// </summary>
        public long Id { get; private set; } = -1;

        /// <summary>
        /// 最新的Id
        /// </summary>
        public long LastId { get; private set; } = -1;

        /// <summary>
        /// 间隔
        /// </summary>
        public int Interval { get; set; } = 1;

        private int windowSize = 30;
        /// <summary>
        /// 一页显示的行数
        /// </summary>
        public int WindowSize
        {
            get { return windowSize; }
            set
            {
                if (value < 10)
                    value = 30;
                if (windowSize != value)
                {
                    windowSize = value;
                }
            }
        }

        /// <summary>
        /// 当前就是最新的视图
        /// </summary>
        public bool IsNewest => Id == Interval * (LastId / Interval);

        /// <summary>
        /// 数据加载中
        /// </summary>
        public bool IsLoading { get; private set; }




        /// <summary>
        /// 通过时间查找数据
        /// </summary>
        public bool IsSearchByTime { get; set; }

        /// <summary>
        /// 查找时间
        /// </summary>
        public DateTime SearchTime { get; set; }

        /// <summary>
        /// 查找Id
        /// </summary>
        public long SearchId { get; set; }



        public ObservableCollection<Lc_Flow> Values { get; } = new ObservableCollection<Lc_Flow>();

        #region Cmd
        public RelayCommand PreViewCmd { get; }
        public RelayCommand NextViewCmd { get; }

        public RelayCommand ToNewestCmd { get; }

        public RelayCommand SearchCmd { get; }

        #endregion
        IBulkDbFlowService bulkDb;
        ParamDictionary paramDictionary;

        public PgFlowTableVm()
        {
            PreViewCmd = new RelayCommand(PreView);
            NextViewCmd = new RelayCommand(NextView);
            ToNewestCmd = new RelayCommand(ToNewest);
            SearchCmd = new RelayCommand(Search);

        }
        [InjectionMethod]
        public void Init(
            IBulkDbFlowService bulkDb,
            ParamDictionary paramDictionary
            )
        {
            this.bulkDb = bulkDb;
            this.paramDictionary = paramDictionary;

            //窗口显示数据条数
            this.paramDictionary.SetBinding(this, nameof(WindowSize), 30);
            this.paramDictionary.SetBinding(this, nameof(Interval), "FLY.Weight2.UI.Client.PgFlowTableVm.Interval", 10);

            bulkDb.PropertyChanged += BulkDB_PropertyChanged;

            this.PropertyChanged += CtrlTableViewModel_PropertyChanged;

            Misc.BindingOperations.SetBinding(bulkDb, nameof(bulkDb.LastId), this, nameof(LastId));

            ToNewest();
        }


        private void BulkDB_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(FObjBase.FObjServiceClient.IsConnected))
            {
                if ((bulkDb as FObjBase.FObjServiceClient).IsConnected)
                {
                    ToNewest();
                }
                else
                {
                    IsLoading = false;
                }
            }
        }

        private void CtrlTableViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {

        }

        bool IsConnected
        {
            get
            {
                return (bulkDb as FObjBase.FObjServiceClient).IsConnected;
            }
        }


        void GetTrendReponse(object asyncContext, object retData)
        {
            IsLoading = false;
            var reponse = retData as Pack_GetTrendReponse<Lc_Flow>;

            //向Values 后面添加数据
            if (reponse.Values != null && reponse.Values.Count > 0)
            {
                //从尾向前排的!!!!

                //现在把数据反转,Id从小排到大
                reponse.Values.Reverse();

                Values.Clear();

                for (int i = 0; i < reponse.Values.Count(); i++)
                {
                    Values.Add(reponse.Values[i]);
                }

                //限制Values长度
                int remove_cnt = Values.Count() - WindowSize;
                for (int i = 0; i < remove_cnt; i++)
                    Values.RemoveAt(0);


                Id = reponse.Values.Last().ID;
                SearchId = reponse.Values.Last().ID;
                SearchTime = reponse.Values.Last().Time;
            }
            else
            {
                Values.Clear();
                //没有任何数据
                Id = -1;
            }
        }

        void Search()
        {
            if (IsSearchByTime)
            {
                Search(SearchTime);
            }
            else
            {
                Search(SearchId);
            }
        }

        /// <summary>
        /// WHERE ID 小于 lastId AND ID % graphparam.Interval == 0 ORDER BY ID DESC LIMIT graphparam.Len
        /// </summary>
        /// <param name="id"></param>
        void Search(long id)
        {
            if (id <= 0)
                return;

            if (!IsConnected)
                return;
            if (IsLoading)
                return;

            IsLoading = true;

            //TODO,计算,是否有重叠的数据
            bulkDb.GetTrend(
                new Pack_GetTrendRequest()
                {
                    Id = id,
                    Interval = Interval,
                    Count = WindowSize
                },
                GetTrendReponse, this);
        }

        /// <summary>
        /// WHERE Time 小于 lastTime AND ID % graphparam.Interval == 0 ORDER BY ID DESC LIMIT graphparam.Len
        /// </summary>
        /// <param name="lastId"></param>
        void Search(DateTime time)
        {
            if (!IsConnected)
                return;
            if (IsLoading)
                return;

            IsLoading = true;
            //TODO,计算,是否有重叠的数据
            bulkDb.GetTrend(
                new Pack_GetTrendRequest()
                {
                    Interval = Interval,
                    Count = WindowSize,
                    IsSearchByTime = true,
                    Time = time
                },
                GetTrendReponse, this);
        }

        /// <summary>
        /// 下一页
        /// </summary>
        void PreView()
        {
            Search(Id - WindowSize * Interval);
        }

        /// <summary>
        /// 上一页
        /// </summary>
        void NextView()
        {

            Search(Id + WindowSize * Interval);
        }

        /// <summary>
        /// 显示最新数据
        /// </summary>
        void ToNewest()
        {
            if (!IsConnected)
                return;
            if (IsLoading)
                return;

            IsLoading = true;
            bulkDb.GetTrend(
                new Pack_GetTrendRequest()
                {
                    Id = 0,
                    Interval = Interval,
                    Count = WindowSize
                },
                GetTrendReponse, this);
        }
    }
    public class PgFlowTableVmUt : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 当前页面最后一行Id
        /// </summary>
        public long Id { get; private set; } = -1;

        /// <summary>
        /// 最新的Id
        /// </summary>
        public long LastId { get; private set; } = -1;

        /// <summary>
        /// 间隔
        /// </summary>
        public int Interval { get; set; } = 1;

        private int windowSize = 30;
        /// <summary>
        /// 一页显示的行数
        /// </summary>
        public int WindowSize
        {
            get { return windowSize; }
            set
            {
                if (value < 10)
                    value = 30;
                if (windowSize != value)
                {
                    windowSize = value;
                }
            }
        }

        /// <summary>
        /// 当前就是最新的视图
        /// </summary>
        public bool IsNewest => Id == Interval * (LastId / Interval);

        /// <summary>
        /// 数据加载中
        /// </summary>
        public bool IsLoading { get; private set; }




        /// <summary>
        /// 通过时间查找数据
        /// </summary>
        public bool IsSearchByTime { get; set; }

        /// <summary>
        /// 查找时间
        /// </summary>
        public DateTime SearchTime { get; set; }

        /// <summary>
        /// 查找Id
        /// </summary>
        public long SearchId { get; set; }


        public List<Lc_Flow> Values { get; } = new List<Lc_Flow>();

        public PgFlowTableVmUt()
        {
            DateTime time = DateTime.Now;

            Random random = new Random();
            int len = 120;
            List<Lc_Flow> bulkdb = new List<Lc_Flow>();
            for (int i = 0; i < len; i++)
            {
                Lc_Flow flow = new Lc_Flow();
                flow.ID = i;
                flow.Time = time + TimeSpan.FromSeconds(i * 7);
                flow.Items = new Lc_FlowItem[5];
                for (int j = 0; j < 5; j++)
                {
                    var flowItem = new Lc_FlowItem();
                    flowItem.Flow = (Math.Sin(i * Math.PI / (len / 2.3)) * 0.6) * 10 + 100 + (random.NextDouble() - 0.5) * 1;
                    flow.Items[j] = flowItem;
                }

                bulkdb.Add(flow);
            }

            WindowSize = 30;
            SearchId = 70;

            LastId = bulkdb.Last().ID;
            IsLoading = true;



            int startIndex = (int)(SearchId - WindowSize);
            int size = WindowSize;
            Values.AddRange(bulkdb.Skip(startIndex).Take(size));



            Id = Values.Last().ID;
            SearchId = Values.Last().ID;
            SearchTime = Values.Last().Time;
        }
    }
}