using FLY.OBJComponents.Common;
using FLY.OBJComponents.IService;
using FLY.OBJComponents.Server.Model;
using FObjBase;
using SQLite;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.OBJComponents.Server
{
    public class BufferError : IBufferAdd<FlyData_WarningHistory>
    {
        IErrorDBModel dBModel;

        public int NewestID { get; private set; }

        public int Count { get; private set; }

        public int Capacity { get; set; } = int.MaxValue;

        public event NotifyBufferChangedEventHandler<FlyData_WarningHistory> BufferChanged;
        public event PropertyChangedEventHandler PropertyChanged;


        public BufferError()
        {

        }
        public void Init(IErrorDBModel dBModel)
        {
            this.dBModel = dBModel;

            Load();
        }
        void Load()
        {
            var n = dBModel.sqliteHelper.ExecuteScalar($"SELECT COUNT(*) FROM {dBModel.TbError.TableName}");

            int count = System.Convert.ToInt32(n);
            NewestID = count - 1;
            Count = count;
        }



        public void Add(FlyData_WarningHistory t)
        {
            var db_errorData = new DB_Error()
            {
                ID = dBModel.TbError.FreeID,//添加 数据库必要的 field
                Time = t.Time,
                ErrCode = t.ErrCode,
                Descrption = t.Description,
                IsOn = t.State == ERR_STATE.ON
            };
            
            //SQLs
            List<string> sqls = new List<string>();
            sqls.Add(SQLiteHelper.GetInsertCommandText(db_errorData));

            dBModel.sqliteHelper.QueryTranAsync(sqls);
            
            NewestID = Count;
            Count++;
        }

        /// <summary>
        /// 清空全部数据
        /// </summary>
        public void Reset()
        {
            //SQLs
            List<string> sqls = new List<string>();
            sqls.Add($"DELECT FROM {dBModel.TbError.TableName}");
            dBModel.sqliteHelper.QueryTranAsync(sqls);
            NewestID = 0;
            Count = 0;
        }

        /// <summary>
        /// 获取指定位置的N个数据
        /// </summary>
        /// <param name="last_id">最后的ID</param>
        /// <param name="count">数量</param>
        /// <param name="asyncCB">回调</param>
        /// <param name="asyncContext">回调里面的上下文</param>
        public async void GetRecord(int last_id, int count, AsyncCBHandler asyncCB, object asyncContext)
        {
            if (Count == 0)
            {
                asyncCB(asyncContext, new GetRecordReponse<FlyData_WarningHistory>()
                {
                    LastID = 0,
                    Items = null
                });
                return;
            }

            await Task.Factory.StartNew(() => {
                var reponse = new GetRecordReponse<FlyData_WarningHistory>();

                var db_errors = dBModel.TbError.Find($"ORDER BY ID LIMIT {last_id-count+1},{count}");
                reponse.LastID = last_id;
                reponse.Items = Map_DB_Errors2FlyData_WarningHistorys(db_errors);
                asyncCB(asyncContext, reponse);
            });
            
        }

        /// <summary>
        /// 获取最新的N个数据
        /// </summary>
        /// <param name="count">数量</param>
        /// <param name="asyncCB">回调</param>
        /// <param name="asyncContext">回调里面的上下文</param>
        public void GetRecord(int count, AsyncCBHandler asyncCB, object asyncContext)
        {
            GetRecord(NewestID, count, asyncCB, asyncContext);
        }

        FlyData_WarningHistory Map_DB_Error2FlyData_WarningHistory(DB_Error dB_Error)
        {
            return new FlyData_WarningHistory()
            {
                Time = dB_Error.Time,
                ErrCode = dB_Error.ErrCode,
                State = dB_Error.IsOn ? ERR_STATE.ON : ERR_STATE.OFF,
                Description = dB_Error.Descrption,
                Accessory = dB_Error.Accessory
            };
        }
        List<FlyData_WarningHistory> Map_DB_Errors2FlyData_WarningHistorys(List<DB_Error> dB_Errors)
        {
            List<FlyData_WarningHistory> flyDatas = new List<FlyData_WarningHistory>();
            foreach (var db_error in dB_Errors)
            {
                flyDatas.Add(Map_DB_Error2FlyData_WarningHistory(db_error));
            }
            return flyDatas;
        }
    }
}
