using System;
using System.Collections.Generic;
using System.Linq;
using FluentScheduler;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.QmsRepository;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.Redis;
using Siger.Middlelayer.Redis.RedisEntities;
using Siger.Middlelayer.Redis.Repositories;
using Siger.Middlelayer.Repository.Response;

namespace Siger.ApiQMS.Tasks
{
    public class QmsParameterConfigJob : IJob
    {
        private static ApiQmsDbContext _context;

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

        public void Execute()
        {
            _context = new ApiQmsDbContext();
            try
            {
                var dbConfigs = RedisCache.Instance.GetDbNameConfigs();                
                foreach (var item in dbConfigs)
                {
                    SyncProductConfig(item.Cid, item.Pid);
                    SyncParameterList(item.Cid, item.Pid);
                    SyncDefaultInfoConfig(item.Cid, item.Pid);
                    SyncParameterMaintainConfig(item.Cid, item.Pid);                                     
                }
                _context.Dispose();
            }
            catch (Exception ex)
            {
                _context.Dispose();
                Logger.WriteLineError(ex.Message);
            }
        }

        private void SyncProductConfig(int companyid, int projectid)
        {
            var products = _context.siger_project_product.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid).ToList();
            var productRepository = new QMSProductNameConfigRepository(companyid, projectid, false);
            try
            {
                foreach (var product in products)
                {
                    var config = new QMSProductNameConfig
                    {
                        ProductID = product.id
                    };
                    productRepository.SetProductConfig(product.name, config);
                }
                var configs = productRepository.GetConfigs();
                foreach(var config in configs)
                {
                    var product = products.FirstOrDefault(t => t.name == config.Key);
                    if(product == null)
                    {
                        productRepository.DeleteConfig(config.Key);
                    }
                }
                productRepository.Dispose();
            }
            catch
            {
                productRepository.Dispose();
            }
        }

        private void SyncParameterMaintainConfig(int companyid, int projectid)
        {
            var repository = new QMSParameterMaintainConfigRepository(companyid, projectid, false);
            var items = repository.GetAllCofigs();
            var configs = _context.siger_qms_parametermaintain_config.Where(t => t.projectid == projectid).ToList();
            var products = _context.siger_project_product.Where(t => t.projectid == projectid &&
                t.status == (int)RowState.Valid).ToList();
            var sections = _context.siger_project_level_section.Where(t => t.projectid == projectid &&
                t.status == (int)RowState.Valid).ToList();
            var standards = _context.siger_qms_inspection_standard.Where(t => t.projectid == projectid &&
                t.status == (int)RowState.Valid).ToList();
            try
            {
                if (configs.Any())
                {
                    foreach (var config in configs)
                    {
                        var key = $"{config.sectionid}_{config.productid}_{config.value}_{config.result}";
                        var model = repository.GetSingleByKey(key);
                        var item = standards.FirstOrDefault(t => t.id == config.itemid);
                        if (model == null && config.status == (int)RowState.Valid)
                        {
                            var product = products.FirstOrDefault(t => t.id == config.productid);
                            var section = sections.FirstOrDefault(t => t.id == config.sectionid);
                            if (product != null && section != null && item != null)
                            {
                                var entity = new QMSParameterMaintainConfig
                                {
                                    ItemID = config.itemid,
                                    ItemName = item.item_en,
                                    ProductID = config.productid,
                                    ProductName = product.name,
                                    SectionID = config.sectionid,
                                    SectionName = section.title,
                                    machineID = config.machineid,
                                    changeTime = DateTime.Now.ToString(ParameterConstant.DateTimeFormat),
                                    downlimit = item.min_value,
                                    uplimit = item.max_value
                                };
                                repository.SetConfig(key, entity);
                            }
                        }
                        else if(model != null && config.status == (int)RowState.Invalid)
                        {
                            repository.DeleteByKey(key);
                        }
                        if (item != null && item.inspection == 0 && config.status == (int)RowState.Valid)//同步监测状态
                        {
                            item.inspection = 1;
                            _context.siger_qms_inspection_standard.Update(item);
                            _context.SaveChanges();
                        }
                    }
                }
                repository.Dispose();
                //同步监测状态
                var notInChecks = standards.Where(t => !configs.Where(q => q.status == (int)RowState.Valid)
                    .Select(q => q.itemid).Contains(t.id) && t.inspection == 1).ToList();
                foreach (var notInCheck in notInChecks)
                {
                    notInCheck.inspection = 0;
                    _context.siger_qms_inspection_standard.Update(notInCheck);
                    _context.SaveChanges();
                }
            }
            catch(Exception ex)
            {
                repository.Dispose();
                Logger.WriteLineError(ex.ToString());                
            }
        }

        private void SyncDefaultInfoConfig(int companyid, int projectid)
        {
            var repository = new QMSDefaultInfoConfigRepository(companyid, projectid, false);
            try
            {
                var configs = repository.GetAllCofigs();
                var datas = _context.siger_qms_defaultinfo_config.Where(t => t.projectid == projectid && t.status == (int)RowState.Valid).ToList();
                var sections = _context.siger_project_level_section.Where(t => t.projectid == projectid &&
                        t.status == (int)RowState.Valid).ToList();
                if (configs.Any())
                {                    
                    foreach (var config in configs)
                    {
                        var data = datas.FirstOrDefault(t => t.key == config.Key);
                        var model = config.Value;
                        if (data != null && data.iscfg == 1)
                        {
                            var section = sections.FirstOrDefault(t => t.id == data.sectionid);
                            model.iscfg = 1;
                            model.machineID = data.machineid;
                            model.SectionID = data.sectionid;
                            model.type = data.type;
                            model.field = data.field;
                            model.SectionName = section?.title ?? "";
                            model.enable = data.enable;
                            model.changeTime = DateTime.Now.ToString(ParameterConstant.DateTimeFormat);
                            repository.SetItemInfoConfig(config.Key, model);
                        }
                        else if((data != null && data.iscfg == 0) || data == null)
                        {
                            repository.DeleteConfig(config.Key);
                        }
                    }
                }
                var keys = configs.Select(t => t.Key).ToList();
                datas = datas.Where(t => t.iscfg == 1 && !keys.Contains(t.key)).ToList();
                foreach(var model in datas)
                {
                    var section = sections.FirstOrDefault(t => t.id == model.sectionid);
                    var config = new QMSDefaultInfoConfig
                    {
                        machineID = model.machineid,
                        type = model.type,
                        field = model.field,
                        SectionID = model.sectionid,
                        SectionName = section?.title ?? "",
                        enable = model.enable,
                        iscfg = 1,
                        changeTime = DateTime.Now.ToString(ParameterConstant.DateTimeFormat),
                    };
                    repository.SetItemInfoConfig(model.key, config);
                }

                repository.Dispose();
            }
            catch(Exception ex)
            {
                repository.Dispose();
                Logger.WriteLineError(ex.ToString());
            }
        }

        private void SyncParameterList(int companyid, int projectid)
        {
            var repository = new QMSParameterListRepository(companyid, projectid);
            var configs = repository.GetAllCofigs();
            var datas = _context.siger_qms_defaultinfo_config.Where(t => t.projectid == projectid);
            if (configs.Any())
            {
                foreach (var config in configs)
                {
                    var data = datas.FirstOrDefault(t => t.key == config.Key);
                    var model = config.Value;
                    if (data == null)
                    {
                        var entity = new siger_qms_defaultinfo_config
                        {
                            key = config.Key,
                            sectionid = 0,
                            machineid = 0,
                            type = "",
                            field = "",
                            enable = 0,
                            iscfg = 0,
                            userid = 0,
                            changetime = string.IsNullOrEmpty(model.changeTime) ? DateTime.Now : model.changeTime.ToDateTime(),
                            projectid = projectid,
                            status = (int)RowState.Valid,
                            description = "",
                        };
                        _context.siger_qms_defaultinfo_config.Add(entity);
                        _context.SaveChanges();
                    }
                }
            }
        }
    }
}
