using FLY.OBJComponents.Server.Model;
using FLY.Thick.FilmCasting.Server.Model;
using FLY.Thick.FilmCasting.UI.DbViewer.Db.ModelAccessory;
using Misc;
using SQLite;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace FLY.Thick.FilmCasting.UI.DbViewer.Db
{
    public class DbHelper : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public const string DefaultDbDirPath = @"D:\film_casting_data";
        public string DbDirPath { get; private set; } = DefaultDbDirPath;

        /// <summary>
        /// 月份路径
        /// </summary>
        public string MonthPath { get; private set; }

        public string DbPathThk
        {
            get
            {
                if (string.IsNullOrEmpty(MonthPath))
                {
                    return System.IO.Path.Combine(DbDirPath, "thickness.sqlite3");
                }
                else
                {
                    return System.IO.Path.Combine(DbDirPath, MonthPath, "thickness.sqlite3");
                }
            }
        }


        public bool IsThkExist { get; private set; }
        public bool IsDbExist
        {
            get
            {
                return IsThkExist;
            }
        }
        public DateTime ThkDbBeginTime { get; private set; }

        public DateTime ThkDbEndTime { get; private set; }

        public DateTime DbBeginTime { get; private set; }

        public DateTime DbEndTime { get; private set; }

        /// <summary>
        /// 出错代码
        /// </summary>
        public string ErrorMsg { get; private set; }

        public bool IsDbErr { get; private set; }

        FLY.Thick.FilmCasting.Server.Model.DbModel dbModelThk = null;
        AccessoryDbModel dbModelAcc = null;
        string DbPathAcc => System.IO.Path.Combine(DbDirPath, "accessory.sqlite3");

        

        public DbHelper()
        {

        }


        /// <summary>
        /// 从表获取数据
        /// </summary>
        /// <param name="monthPath">月份文件夹， null为近2个月</param>
        /// <returns></returns>
        public bool Init(string dbDirPath, string monthPath)
        {
            DbDirPath = dbDirPath;
            MonthPath = monthPath;
            IsThkExist = System.IO.File.Exists(DbPathThk);

            if (!IsDbExist)
            {
                //没有任何数据
                ErrorMsg = $"不能找到任何数据";
                IsDbErr = true;
                return false;
            }

            if (IsThkExist)
            {
                if (!Init_thk())
                {
                    return false;
                }
            }


            dbModelAcc = new AccessoryDbModel(DbPathAcc);
            dbModelAcc.Init();

            DbBeginTime = ThkDbBeginTime;
            DbEndTime = ThkDbEndTime;

            return true;
        }

        bool Init_thk()
        {
            try
            {
                dbModelThk = new FLY.Thick.FilmCasting.Server.Model.DbModel(DbPathThk);
                if (!dbModelThk.InitNoBuild())
                {
                    ErrorMsg = $"{DbPathThk} 数据库格式异常";
                    IsDbErr = true;
                    return false;
                }
                //获取 第1幅扫描数据的时间
                string cmd = $"SELECT Time FROM {dbModelThk.TbScanData.TableName} ORDER BY ID LIMIT 1";
                var ret = dbModelThk.sqliteHelper.ExecuteScalar(cmd);
                ThkDbBeginTime = System.Convert.ToDateTime(ret);

                //获取 最后1幅扫描数据的时间
                cmd = $"SELECT Time FROM {dbModelThk.TbScanData.TableName} ORDER BY ID DESC LIMIT 1";
                ret = dbModelThk.sqliteHelper.ExecuteScalar(cmd);
                ThkDbEndTime = System.Convert.ToDateTime(ret);
            }
            catch (Exception e)
            {
                ErrorMsg = e.Message;
                IsDbErr = true;
                return false;
            }
            return true;
        }

        /// <summary>
        /// 获取月份列表
        /// </summary>
        /// <returns></returns>
        public List<string> GetMonthList()
        {
            List<string> monthList = new List<string>();
            //枚举文件夹 全部 yyyy-MM 格式的数据
            Regex regex = new Regex(@"\A(\d\d\d\d)-(\d\d)\z");
            var dirInfo = new DirectoryInfo(DbDirPath);
            var dirInfos = dirInfo.GetDirectories();
            if (dirInfos == null || dirInfos.Count() == 0)
                return monthList;

            foreach (var dinfo in dirInfos)
            {
                var match = regex.Match(dinfo.Name);
                if (match.Success)
                {
                    if (!int.TryParse(match.Groups[1].Value, out int y))
                        continue;
                    if (!int.TryParse(match.Groups[2].Value, out int m))
                        continue;
                    if (m > 12 || m < 1)
                        continue;//异常
                    if (y < 1900 || y > 2100)
                        continue;//异常

                    monthList.Add($"{match.Groups[1].Value}-{match.Groups[2].Value}");
                }
            }
            return monthList;
        }

        /// <summary>
        /// 删除profile
        /// </summary>
        /// <param name="profile"></param>
        public void DeleteProfile(FLY.Thick.FilmCasting.Server.Model.Db_Profile profile)
        {
            if (IsProfileDeleted(profile.ID, profile.StartTime))
            {
                //已经删除
                return;
            }
            else
            {
                dbModelAcc.TbProfileDelete.Add(new Db_ProfileDelete()
                {
                    ID = dbModelAcc.TbProfileDelete.FreeID,
                    Time = DateTime.Now,
                    ProfileID = profile.ID,
                    ProfileTime = profile.StartTime
                });
            }
        }
        /// <summary>
        /// 恢复删除的profile
        /// </summary>
        /// <param name="profileDeleteID"></param>
        public void RecoverProfile(Int64 profileDeleteID)
        {
            dbModelAcc.sqliteHelper.ExecuteNonQuery(
                $"DELETE FROM {dbModelAcc.TbProfileDelete.TableName}" +
                $" WHERE ID = {profileDeleteID}");
        }

        bool IsProfileDeleted(Int64 profileId, DateTime startTime)
        {
            if (dbModelAcc.TbProfileDelete.Find(
                $"WHERE {nameof(Db_ProfileDelete.ProfileID)}={profileId} " +
                $"AND {nameof(Db_ProfileDelete.ProfileTime)}={startTime.ToStringOfSQLiteFieldType()}").Count() > 0)
            {
                //已经删除
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 获取删除profile记录列表
        /// </summary>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <returns></returns>
        public List<Db_ProfileDelete> GetProfileDeleteList(DateTime starttime, DateTime endtime)
        {
            string startTime_str = starttime.Date.ToStringOfSQLiteFieldType();
            string endTime_str = endtime.Date.AddDays(1).ToStringOfSQLiteFieldType();
            string sql =
                $"WHERE {nameof(Db_ProfileDelete.Time)} >= {startTime_str} AND {nameof(Db_ProfileDelete.Time)} <= {endTime_str}";


            return dbModelAcc.TbProfileDelete.Find(sql);
        }


        /// <summary>
        /// 获取profiles,已经被删除的，不显示
        /// </summary>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="pname"></param>
        /// <returns></returns>
        public List<Db_Profile> GetProfileList(DateTime starttime, DateTime endtime, string pname, string batch)
        {
            string startTime_str = starttime.Date.ToStringOfSQLiteFieldType();
            string endTime_str = endtime.Date.AddDays(1).ToStringOfSQLiteFieldType();
            string pname_str = $"%{pname}%".ToStringOfSQLiteFieldType();
            string batch_str = $"%{batch}%".ToStringOfSQLiteFieldType();
            string sql =
                "WHERE " +
                "(" +
                $"({nameof(Db_Profile.StartTime)} > {startTime_str} AND {nameof(Db_Profile.StartTime)} < {endTime_str})" +
                $" OR ({nameof(Db_Profile.EndTime)} > {startTime_str} AND {nameof(Db_Profile.EndTime)} < {endTime_str})" +
                ") " +
                $" AND ({nameof(Db_Profile.PName)} LIKE {pname_str})" +
                $" AND ({nameof(Db_Profile.Batch)} LIKE {batch_str})";

            var db_profiles = dbModelThk.TbProfile.Find(sql);

            //剔除 在 accessory 中记录的删除行
            db_profiles.RemoveAll(p => IsProfileDeleted(p.ID, p.StartTime));

            return db_profiles;
        }


        public DbProfilePack GetProfilePack(Db_Profile db_Profile)
        {
            DbProfilePack profilePack = new DbProfilePack();
            profilePack.Profile = db_Profile;
            GetProfilePack_thk(db_Profile, profilePack);
            return profilePack;
        }


        void GetProfilePack_thk(Db_Profile db_Profile, DbProfilePack profilePack)
        {
            string startTime_str = db_Profile.StartTime.ToStringOfSQLiteFieldType();
            string endTime_str = db_Profile.EndTime.ToStringOfSQLiteFieldType();

            string condition;

            condition =
                $"WHERE {nameof(Db_ScanData.Time)}>={startTime_str}" +
                $" AND {nameof(Db_ScanData.EndTime)}<={endTime_str}";

            var db_scandatas = dbModelThk.TbScanData.Find(condition);
            var lc_scandatas = Lc_AutoMapperProfile.Mapper.Map<List<Db_ScanData>, List<Lc_ScanData>>(db_scandatas);
            profilePack.ScanDatas = lc_scandatas;

            condition =
                $"WHERE {nameof(Db_Error.Time)}>={startTime_str}" +
                $" AND {nameof(Db_Error.Time)}<={endTime_str}";
            var db_errors = dbModelThk.TbError.Find(condition);
            profilePack.Errors = db_errors;



        }

    }




}
