using Siger.DataSchedule.Infrastructure.Extend;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper.CheckTrace.Repostriories;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.QmsRepository;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.Redis;
using System;
using System.Collections.Generic;
using System.Linq;

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

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

        public void AfterExecute(ScheduleContext context)
        {

        }

        public void Undo()
        {

        }
    }

    public class QmsDataMigrationJob
    {
        private static ApiQmsDbContext _context;

        static QmsDataMigrationJob()
        {
            _context = new ApiQmsDbContext();
        }

        public void Execute()
        {
            _context = new ApiQmsDbContext();
            try
            {
                var state = _context.siger_system_config.FirstOrDefault(t => t.status == (int)RowState.Valid &&
                            t.key == SystemConfigKey.QmsDataMigrationStatus);
                if ((state != null && state.value.ToInt() != (int)RowState.Valid) || state == null)
                {
                    _context.Dispose();
                    return;
                }
                var dbConfigs = RedisCache.Instance.GetDbNameConfigs();
                foreach (var item in dbConfigs)
                {
                    try
                    {
                        SyncBigDataToMiddleDataBase(item.Pid, item.Cid);
                        SyncMiddleDataToBigDataBase();
                    }
                    catch (Exception e)
                    {
                        Logger.WriteLineError(e.Message);
                    }
                }
                _context.Dispose();
            }
            catch (Exception ex)
            {
                _context.Dispose();
                Logger.WriteLineError(ex.Message);
            }
        }

        /// <summary>
        /// 迁移大数据的数据到中间层(老数据迁移
        /// </summary>
        public void SyncBigDataToMiddleDataBase(int projectid, int companyid)
        {
            var _traceRepository = new TraceDataRepository(companyid, projectid);
            var datas = _traceRepository.GetSnTraceList(projectid);
            var traces = _context.siger_check_sn_trace_inspection.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid &&
                datas.Select(q => q.ID).Contains(t.trace_id)).ToList();
            datas = datas.Where(t => !traces.Select(q => q.trace_id).Contains(t.ID)).ToList();
            var insertModels = new List<siger_check_sn_trace_inspection>();
            var insertDetailModels = new List<siger_check_sn_trace_detail>();
            foreach (var data in datas)
            {
                var model = new siger_check_sn_trace_inspection
                {
                    trace_id = data.ID,
                    testroom = "",
                    productid = data.ProductID,
                    materialid = data.MaterialID,
                    sectionid = data.SectionID,
                    sn = data.SN,
                    routeid = data.RouteID,
                    check_type = data.CheckType,
                    check_status = (int)SendCheckStatus.Completed,
                    result = data.Result.ToUpper() == "OK" ? ((int)SendTestType.Qalified).ToString() : ((int)SendTestType.Unqualified).ToString(),
                    send_mid = data.UserID,
                    send_time = data.CreateTime,
                    check_mid = data.UserID,
                    check_time = data.CreateTime,
                    inspection_type = (int)InspectionType.ManualCollection,
                    projectid = projectid,
                    reason = "",
                    workorder = data.WorkOrder,
                    recieve_mid = data.UserID,
                    recieve_time = data.CreateTime,
                    checking_mid = data.UserID,
                    checking_time = data.CreateTime
                };
                var dataDetails = _context.siger_check_sn_trace_detail.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid &&
                    data.ID == t.TraceID).ToList();
                if (dataDetails.Any())
                {
                    continue;
                }
                var details = _traceRepository.GetSingleTraceDetailList(data.ID, projectid);
                var numberIndexs = _context.siger_check_partindex.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid &&
                    details.Select(q => q.ID).Contains(t.trace_detailid)).ToList();
                var number = 0;
                foreach (var detail in details)
                {
                    var numberIndex = numberIndexs.FirstOrDefault(t => t.trace_detailid == detail.ID);
                    var detailModel = new siger_check_sn_trace_detail
                    {
                        TraceID = detail.TraceID,
                        ItemID = detail.ItemID,
                        Result = detail.Result,
                        Value = detail.Value,
                        ItemName = detail.ItemName,
                        SN = string.IsNullOrEmpty(detail.SN) ? model.sn : detail.SN,
                        NumberIndex = numberIndex?.partindex ?? 1,
                        projectid = projectid,
                        CreateTime = data.CreateTime
                    };
                    insertDetailModels.Add(detailModel);
                    if (detailModel.NumberIndex > number)
                    {
                        number = detailModel.NumberIndex;
                    }
                }
                model.number = number;
                insertModels.Add(model);
            }

            foreach (var trace in traces)
            {
                var dataDetails = _context.siger_check_sn_trace_detail.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid &&
                    trace.trace_id == t.TraceID).ToList();
                if (dataDetails.Any())
                {
                    continue;
                }
                var details = _traceRepository.GetSingleTraceDetailList(trace.trace_id, projectid);
                var numberIndexs = _context.siger_check_partindex.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid &&
                    details.Select(q => q.ID).Contains(t.trace_detailid)).ToList();
                foreach (var detail in details)
                {
                    var numberIndex = numberIndexs.FirstOrDefault(t => t.trace_detailid == detail.ID);
                    var detailModel = new siger_check_sn_trace_detail
                    {
                        TraceID = detail.TraceID,
                        ItemID = detail.ItemID,
                        Result = detail.Result,
                        Value = detail.Value,
                        ItemName = detail.ItemName,
                        SN = string.IsNullOrEmpty(detail.SN) ? trace.sn : detail.SN,
                        NumberIndex = numberIndex?.partindex ?? 1,
                        projectid = projectid,
                        CreateTime = (trace.check_time.HasValue && trace.check_time != DateTime.MinValue) ? trace.check_time.Value : DateTime.Now
                    };
                    insertDetailModels.Add(detailModel);
                }
            }

            _context.siger_check_sn_trace_inspection.AddRange(insertModels);
            _context.siger_check_sn_trace_detail.AddRange(insertDetailModels);
            _context.SaveChanges();
        }

        public void SyncMiddleDataToBigDataBase()
        {
            return;
        }
    }
}
