using FLY.OBJComponents.Server;
using FLY.OBJComponents.Server.Model;
using FLY.Thick.FilmCasting.IService;
using FObjBase;
using FObjBase.Reflect;
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.Thick.FilmCasting.Server.Model
{
    /// <summary>
    /// 数据库 写操作
    /// </summary>
    public class HistoryDb : IShareDbService
    {
        /// <summary>
        /// 本地数据库
        /// </summary>
        public LocalDb localDb;
        DbModel dbModel;
        public BufferError ErrorBuffer;

        #region IShareDbService
        [Push(typeof(ProfileChangedEventArgs))]
        public event EventHandler ProfileChanged;

        [Push(typeof(ScanDataAddedEventArgs))]
        public event EventHandler ScanDataAdded;
        #endregion


        /// <summary>
        /// 
        /// </summary>
        /// <param name="dBModel"></param>
        /// <param name="orgDBModel"></param>
        /// <param name="localDb"></param>
        public void Init(DbModel dBModel, LocalDb localDb)
        {
            this.dbModel = dBModel;
            this.localDb = localDb;
            ErrorBuffer = new BufferError();
            ErrorBuffer.Init(dBModel.TbError);
        }


        public void AddProfile( Db_Profile profile )
        {
            AddProfile(profile, DateTime.Now);
        }

        /// <summary>
        /// 保存产品参数
        /// </summary>
        public void AddProfile(
            Db_Profile profile, DateTime startTime
            )
        {
            //把上一次结束掉
            if (localDb.IsProfileFinished == false)
            {
                FinishProfile();
            }

            //添加 数据库必要的 field
            profile.ID = dbModel.TbProfile.FreeID;
            profile.StartTime = startTime;
            profile.EndTime = DateTime.Now;
            //SQL
            List<string> sqls = new List<string>();
            sqls.Add(SQLiteHelper.GetInsertCommandText(profile));

            dbModel.sqliteHelper.QueryTranAsync(sqls);


            //本地数据备份
            localDb.CurrProfile = profile;
            localDb.NotifyPropertyChanged(nameof(localDb.ProfileStartTime));
            localDb.NotifyPropertyChanged(nameof(localDb.ProfileEndTime));
            localDb.NotifyPropertyChanged(nameof(localDb.IsProfileFinished));

            #region IDBShareService
            ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
            {
                isInsert = true,
                profile = profile
            });
            #endregion
        }

        /// <summary>
        /// 修改产品参数
        /// </summary>
        /// <param name="profile"></param>
        public void UpdateProfile(
                Db_Profile profile
            )
        {
            if (localDb.CurrProfile == null || //没有数据！！！！
                localDb.IsProfileFinished == true)//生产已经结束了
                return;

            //添加 数据库必要的 field
            profile.ID = localDb.CurrProfile.ID;
            profile.StartTime = localDb.CurrProfile.StartTime;
            profile.EndTime = localDb.CurrProfile.EndTime;
            profile.FilmLength = localDb.CurrProfile.FilmLength;

            //SQL
            List<string> sqls = new List<string>();
            sqls.Add(SQLiteHelper.GetUpdateCommandText(profile, $"WHERE ID = {profile.ID}"));

            dbModel.sqliteHelper.QueryTranAsync(sqls);


            //本地数据备份
            localDb.CurrProfile = profile;

            #region IDBShareService
            ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
            {
                isInsert = false,
                profile = profile
            });
            #endregion
        }

        /// <summary>
        /// 下辊，结束当前产品生产
        /// </summary>
        public void FinishProfile()
        {

            if (localDb.IsProfileFinished)
                return;

            //SQL
            dbModel.sqliteHelper.ExecuteNonQuery(
                $"UPDATE {dbModel.TbProfile.TableName} SET {nameof(Db_Profile.IsFinished)} = {true} WHERE ID = {localDb.CurrProfile.ID}");

            localDb.CurrProfile.IsFinished = true;
            localDb.NotifyPropertyChanged(nameof(localDb.IsProfileFinished));

            #region IDBShareService
            ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
            {
                isInsert = false,
                profile = localDb.CurrProfile
            });
            #endregion
        }

        /// <summary>
        /// 不需设置 DB_ScanData 内 ProfileID, 自动设置！
        /// </summary>
        public void AddScanData(
            Lc_ScanData scanData)
        {

            //添加 数据库必要的 field
            scanData.ID = dbModel.TbScanData.FreeID;
            scanData.ProfileID = localDb.CurrProfile.ID;

            //SQLs
            List<string> sqls = new List<string>();
            var db_scandata = Lc_AutoMapperProfile.Mapper.Map<Db_ScanData>(scanData);
            sqls.Add(SQLiteHelper.GetInsertCommandText(db_scandata));


            sqls.Add(
                $"UPDATE {dbModel.TbProfile.TableName}" +
                $" SET {nameof(Db_Profile.EndTime)}={scanData.EndTime.ToStringOfSQLiteFieldType()}" +
                $" , {nameof(Db_Profile.FilmLength)}={scanData.FilmPosition}" +
                $" WHERE ID={localDb.CurrProfile.ID}");
            
            dbModel.sqliteHelper.QueryTranAsync(sqls);

            //本地数据备份
            localDb.CurrProfile.EndTime = scanData.EndTime;
            localDb.CurrProfile.FilmLength = scanData.FilmPosition;
            localDb.NotifyPropertyChanged(nameof(localDb.ProfileEndTime));

            #region IDBShareService
            ScanDataAdded?.Invoke(this, new ScanDataAddedEventArgs()
            {
                scandata = scanData
            });

            ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
            {
                isInsert = false,
                profile = localDb.CurrProfile
            });
            
            #endregion
        }


        /// <summary>
        /// 不需设置 DB_ScanData 内 ProfileID, 自动设置！
        /// </summary>
        public void AddSample(
            Lc_Sample sampleData)
        {
            //添加 数据库必要的 field
            sampleData.ID = dbModel.TbSample.FreeID;

            //SQLs
            List<string> sqls = new List<string>();
            var db_sampledata = Lc_AutoMapperProfile.Mapper.Map<Db_Sample>(sampleData);
            sqls.Add(SQLiteHelper.GetInsertCommandText(db_sampledata));

            dbModel.sqliteHelper.QueryTranAsync(sqls);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="db_errorData"></param>
        public void AddErrorData(
            Db_Error db_errorData
            )
        {
            //添加 数据库必要的 field
            db_errorData.ID = dbModel.TbError.FreeID;

            //SQLs
            List<string> sqls = new List<string>();
            sqls.Add(SQLiteHelper.GetInsertCommandText(db_errorData));

            dbModel.sqliteHelper.QueryTranAsync(sqls);
        }

        #region IDBShareService
        /// <summary>
        /// 
        /// </summary>
        /// <param name="asyncDelegate"></param>
        /// <param name="asyncContext"></param>
        public void GetProfile(AsyncCBHandler asyncDelegate, object asyncContext)
        {
            if (localDb.CurrProfile != null)
            {
                asyncDelegate.Invoke(asyncContext, localDb.CurrProfile);
            }
            else
            {
                asyncDelegate.Invoke(asyncContext, null);
            }
        }
        #endregion
    }
}
