using CommunityToolkit.Mvvm.Input;
using FLY.OBJComponents.Common;
using FLY.OBJComponents.IService;
using Misc;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Controls;
using Unity;

namespace FLY.Thick.Base.UI
{
    /// <summary>
    /// Page_Flow.xaml 的交互逻辑
    /// </summary>
    public partial class PgErrorAllTable : Page
    {

        PgErrorAllTableVm viewModel;
        /// <summary>
        /// 
        /// </summary>
        public PgErrorAllTable()
        {
            InitializeComponent();
        }

        [InjectionMethod]
        public void Init(
            IWarningSystem2Service warning,
            ParamDictionary paramDictionary,
            ToDescriptionHandler toDescription = null)
        {
            //界面........................................

            viewModel = new PgErrorAllTableVm();
            viewModel.Init(warning, paramDictionary, toDescription);
            this.DataContext = viewModel;

        }
    }

    public class PgErrorAllTableVm : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

        /// <summary>
        /// 最新的Id
        /// </summary>
        public long LastId { get; protected 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 == LastId;

        /// <summary>
        /// 数据加载中
        /// </summary>
        public bool IsLoading { get; protected 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<FlyData_WarningHistory> Values { get; } = new ObservableCollection<FlyData_WarningHistory>();

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

        public RelayCommand ToNewestCmd { get; }

        public RelayCommand SearchCmd { get; }

        #endregion
        IWarningSystem2Service warning;
        ParamDictionary paramDictionary;
        ToDescriptionHandler toDescription;
        public PgErrorAllTableVm()
        {
            PreViewCmd = new RelayCommand(PreView);
            NextViewCmd = new RelayCommand(NextView);
            ToNewestCmd = new RelayCommand(ToNewest);
            SearchCmd = new RelayCommand(Search);

        }

        public void Init(
            IWarningSystem2Service warning,
            ParamDictionary paramDictionary,
            ToDescriptionHandler toDescription
            )
        {
            this.warning = warning;
            this.paramDictionary = paramDictionary;
            this.toDescription = toDescription;

            //窗口显示数据条数
            this.paramDictionary.SetBinding(this, nameof(WindowSize), 30);

            this.warning.PropertyChanged += BulkDB_PropertyChanged;

            this.PropertyChanged += CtrlTableViewModel_PropertyChanged;

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

            ToNewest();
        }


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

        private void CtrlTableViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {

        }

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


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

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

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

                Values.Clear();

                for (int i = 0; i < response.Values.Count(); i++)
                {
                    var error = response.Values[i].Clone();
                    if (toDescription != null)
                        error.Description = toDescription(error.ErrCode);

                    Values.Add(error);
                }

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


                Id = response.Values.Last().ID;
                SearchId = response.Values.Last().ID;
                SearchTime = response.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,计算，是否有重叠的数据
            warning.GetTrend(
                new Pack_GetTrendRequest()
                {
                    Id = id,
                    Interval = 1,
                    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,计算，是否有重叠的数据
            warning.GetTrend(
                new Pack_GetTrendRequest()
                {
                    Interval = 1,
                    Count = WindowSize,
                    IsSearchByTime = true,
                    Time = time
                },
                GetTrendReponse, this);
        }

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

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

            Search(Id + WindowSize * 1);
        }

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

            IsLoading = true;
            warning.GetTrend(
                new Pack_GetTrendRequest()
                {
                    Id = 0,
                    Interval = 1,
                    Count = WindowSize
                },
                GetTrendReponse, this);
        }
    }
    public class PgErrorAllTableVmUt : PgErrorAllTableVm
    {

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

            Random random = new Random();
            int len = 120;
            List<FlyData_WarningHistory> bulkdb = new List<FlyData_WarningHistory>();


            for (int i = 0; i < len; i++)
            {
                var error = new FlyData_WarningHistory();
                error.ID = i;
                error.Time = time + TimeSpan.FromSeconds(i * 7);
                error.ErrCode = i % 10;
                error.Description = $"hhah {i}";
                error.State = i % 3 == 0 ? ERR_STATE.ON : ERR_STATE.OFF;

                bulkdb.Add(error);
            }

            WindowSize = 30;
            SearchId = 70;

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



            int startIndex = (int)(SearchId - WindowSize);
            int size = WindowSize;
            var values = bulkdb.Skip(startIndex).Take(size);
            foreach (var val in values)
                Values.Add(val);

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