using Siger.CommonUtil;
using Siger.DataSchedule.Infrastructure.Extend;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Dapper.CheckTrace.Constant;
using Siger.Middlelayer.Dapper.CheckTrace.Data;
using Siger.Middlelayer.Dapper.CheckTrace.Repostriories;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.QmsRepository;
using Siger.Middlelayer.Redis;
using Siger.Middlelayer.Redis.RedisEntities;
using Siger.Middlelayer.Repository;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Siger.Schedule.QmsModule
{
    public class QmsCreateTraceTableJobSchedule : IScheduleJob
    {
        QmsCreateTraceTableJob createTableJob;
        public void PreInit(ScheduleContext context)
        {
            Logger.RegisterLogEngine(Module.Qms);
            createTableJob = new QmsCreateTraceTableJob();
        }

        public void Execute(ScheduleContext context)
        {
            createTableJob.Execute();
        }

        public void AfterExecute(ScheduleContext context)
        {

        }

        public void Undo()
        {

        }
    }

    public class QmsCreateTraceTableJob
    {
        private static ApiQmsDbContext _context;
        private static ApiConfigDbContext _configContext;

        static QmsCreateTraceTableJob()
        {
            _context = new ApiQmsDbContext();
            _configContext = new ApiConfigDbContext();
        }

        private IEnumerable<DbNameConfig> GetDbNameConfigs()
        {
            var dbConfigs = new List<DbNameConfig>();
            RedisOpHelper opHelper = new RedisOpHelper();
            var configs = opHelper.HGetAll(RedisCache.DbNameConfigHash);
            foreach (var config in configs)
            {
                dbConfigs.Add(Middlelayer.Common.Helpers.JsonHelper.DeserializerJsonResult<DbNameConfig>(config.Value));
            }

            return dbConfigs.OrderBy(q => q.Cid);
        }

        public void Execute()
        {
            _context = new ApiQmsDbContext();
            _configContext = new ApiConfigDbContext();
            try
            {
                var dbConfigs = GetDbNameConfigs();
                foreach (var item in dbConfigs)
                {
                    try
                    {
                        if (item.Cid > 0 && item.Pid > 0)
                        {
                            CreateTraceTable(item.Pid, item.Cid);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.WriteLineError(e.Message);
                    }
                }
                _context.Dispose();
                _configContext.Dispose();
            }
            catch (Exception ex)
            {
                _context.Dispose();
                _configContext.Dispose();
                Logger.WriteLineError(ex.Message);
            }
        }

        private void CreateTraceTable(int pid, int cid)
        {
            var projectInfo = _configContext.siger_project.FirstOrDefault(q => q.id == pid);
            if (projectInfo == null)
            {
                return;
            }
            var _traceRepostory = new TraceDetailTableRepository(cid, pid);

            var traceIsExsit = _traceRepostory.TableIsExsit(TabelNameConstant.SnTraceTable, $"{cid}_{pid}");
            if (!traceIsExsit)
            {
                _traceRepostory.CreateTable(TabelNameConstant.SnTraceTable, TabelNameConstant.SnTraceTable, 1);
            }
            var subTableIsExsit = _traceRepostory.TableIsExsit(TabelNameConstant.SubTableTable, $"{cid}_{pid}");
            if (!subTableIsExsit)
            {
                _traceRepostory.CreateTable(TabelNameConstant.SubTableTable, TabelNameConstant.SubTableTable, 1);
            }
            var now = DateTime.Now.ToString(ParameterConstant.MouthFirstDay).ToDateTime();
            var startTime = "2020-03-01 00:00:00".ToDateTime();
            var projectStartTime = UnixTimeHelper.ConvertIntDate(projectInfo.createtime).ToDateTime().ToString(ParameterConstant.MouthFirstDay).ToDateTime();
            startTime = startTime > projectStartTime ? startTime : projectStartTime;
            for (var time = startTime; time <= now; time = time.AddMonths(1))
            {
                var detailTableName = $"{TabelNameConstant.SnTraceDetailTable}_{time.Year}{time.Month.ToString("00")}";
                var detailIsExsit = _traceRepostory.TableIsExsit(detailTableName, $"{cid}_{pid}");
                if (detailIsExsit)
                {
                    var detailTable = _traceRepostory.GetSubTableInfo(detailTableName, TabelNameConstant.SnTraceDetailTable);
                    if (detailTable == null)
                    {
                        var minid = _traceRepostory.GetTableMinID(detailTableName);
                        var maxid = _traceRepostory.GetTableMaxID(detailTableName);
                        _traceRepostory.InsertSubTable(new SubTable
                        {
                            name = detailTableName,
                            tablename = TabelNameConstant.SnTraceDetailTable,
                            startid = minid,
                            endid = maxid,
                            validtime = time.AddMonths(-1),
                            createtime = DateTime.Now,
                            status = (int)RowState.Valid
                        });
                    }
                    continue;
                }
                var startid = 1L;
                if (time > startTime)
                {
                    var lastDetailTableName = $"{TabelNameConstant.SnTraceDetailTable}_{time.AddMonths(-1).Year}{time.AddMonths(-1).Month.ToString("00")}";
                    var lastDetailTable = _traceRepostory.GetSubTableInfo(lastDetailTableName, TabelNameConstant.SnTraceDetailTable);
                    if (lastDetailTable == null)
                    {
                        var minid = _traceRepostory.GetTableMinID(lastDetailTableName);
                        var maxid = _traceRepostory.GetTableMaxID(lastDetailTableName);
                        _traceRepostory.InsertSubTable(new SubTable
                        {
                            name = lastDetailTableName,
                            tablename = TabelNameConstant.SnTraceDetailTable,
                            startid = minid,
                            endid = maxid,
                            validtime = time.AddMonths(-1),
                            createtime = DateTime.Now,
                            status = (int)RowState.Valid
                        });
                    }
                    else
                    {
                        var maxId = _traceRepostory.GetTableMaxID(lastDetailTableName);
                        startid = maxId + 1;
                        _traceRepostory.UpdateSubTableEndId(lastDetailTable.id, maxId);
                    }
                }
                _traceRepostory.CreateTable(TabelNameConstant.SnTraceDetailTable, detailTableName, startid);
                _traceRepostory.InsertSubTable(new SubTable
                {
                    name = detailTableName,
                    tablename = TabelNameConstant.SnTraceDetailTable,
                    startid = startid,
                    endid = 0,
                    validtime = time,
                    createtime = DateTime.Now,
                    status = (int)RowState.Valid
                });
            }
        }
    }
}
