using Siger.DataSchedule.Infrastructure.Extend;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.DashboardRepository;
using Siger.Middlelayer.KpiRespository;
using Siger.Middlelayer.KpiRespository.Entities;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Redis;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Share.Enum.ModuleEnum;
using Siger.Middlelayer.Share.ModuleEnum;
using Siger.Middlelayer.Utility.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;


namespace Siger.Schedule.KpiModule
{
    public class KpiAutoRelationSchedule : IScheduleJob
    {
        KpiAutoRelation andonHelper;
        public void PreInit(ScheduleContext context)
        {
            Logger.RegisterLogEngine(Module.Kpi);
            andonHelper = new KpiAutoRelation();
        }
        public void Execute(ScheduleContext context)
        {
            andonHelper.Execute();
        }


        public void AfterExecute(ScheduleContext context)
        {

        }


        public void Undo()
        {

        }
    }
    public class KpiAutoRelation
    {
        private static  ApiKpiDbContext _context;
        private static ApiDashboardDbContext _dashboardcontext;
        private static ApiConfigDbContext _configcontext;
        static KpiAutoRelation()
        {
            _context = new ApiKpiDbContext();
            _dashboardcontext = new ApiDashboardDbContext();
            _configcontext = new ApiConfigDbContext();
        }
        /// <summary>
        /// 
        /// </summary>
        public void Execute()
        {
            
            var dbConfigs = RedisCache.Instance.GetDbNameConfigs();
            foreach (var dbNameConfig in dbConfigs)
            {
                if (string.IsNullOrWhiteSpace(dbNameConfig.RedisDbName))
                {
                    Logger.WriteLineError($"KpiTasksJob DbNameConfig setting error, can not find redisdbname by cid:{dbNameConfig.Cid}, pid:{dbNameConfig.Pid}.");
                    continue;
                }
                if (dbNameConfig.Pid != 160)
                    continue;
                TaskRelation(dbNameConfig.Pid);
            }
        }
        /// <summary>
        /// 执行关联
        /// </summary>
        /// <param name="projectId"></param>
        public void TaskRelation(int projectId)
        {
            try
            {
                //前一天
                var currDate = System.DateTime.Now.Date.AddDays(-1);
                var querter = DateTimeHelper.GetQuarterByMonth(currDate.Month);
                var weekofYear = DateTimeHelper.GetWeekOfYear(currDate);
                var relationCfg = Getlist(projectId);
                var cycleText = string.Empty;
              
                foreach (var r in relationCfg)
                {
                    var itemObj = _context.siger_project_kpi_item.FirstOrDefault(f => f.projectId == projectId && f.id == r.Item);
                    if (itemObj == null)
                        continue;
                    if (itemObj.KpiCycle != KpiCycleEnum.Day)
                        continue;
                    var _autoTarget = (DashboardTotalRate)r.AutoTarget;
                    cycleText = KpiCycleEnumHelper.CycleTypeText(itemObj.KpiCycle, querter, weekofYear, currDate);
                    var Record = _context.siger_project_kpi_tasklist.FirstOrDefault(f => f.projectId == projectId && f.cycle == cycleText && f.ItemId == r.Item);
  
                    var chanels = GetLine(projectId, r.Line);
                    var datattls = _dashboardcontext.siger_project_auto_calculation_data_ttl.Where(f => f.projectid == projectId && f.busidate == currDate && chanels.Contains( f.section) && f.ratetype == _autoTarget);
                    if (!datattls.Any())
                    {
                        Logger.WriteLineInfo($"pid:{ projectId} Line:{ r.Line } station:{r.Section} item:{itemObj.Item} autoItem{EnumHelper.GetEnumDesc(_autoTarget)}  cycletext:{cycleText}can't find any totaldata");
                        continue;
                    }
                    var numeratorTotal = datattls.Sum(s => s.numerator);
                    var denominaTotal = datattls.Sum(s => s.denominator);
                    var ratePercent = 0d;
                    if (_autoTarget== DashboardTotalRate.OEE || _autoTarget== DashboardTotalRate.YieldAchieved)
                    {
                        //百分比
                        if (denominaTotal > 0)
                        {
                            ratePercent = Math.Round(numeratorTotal / denominaTotal, 2) * 100;
                        }

                    }else
                    {
                        //实际值
                        ratePercent = numeratorTotal;
                    }
                    var state = GetState(ratePercent, itemObj.TargetVal, itemObj);
                    var typeResult = (int)KpiTaskType.Normal;
                    var excption = KpiExecption.Default;
                    var taskResult = KpiTaskResult.NoConfg;
                    if (state == (int)KpiTaskResult.Exception)
                    {
                        typeResult = (int)KpiTaskType.Exception;
                        taskResult = KpiTaskResult.Exception;
                    }else if (state== (int)KpiTaskResult.Normal)
                    {
                        taskResult = KpiTaskResult.Normal;
                    }
                    if (Record != null)
                    {
                        Record.TargetVal = itemObj.TargetVal;
                        Record.ActVal = ratePercent;
                        Record.Type = typeResult;
                        Record.Excption = excption;
                        Record.Result = taskResult;
                        Record.Remark = "自动关联";
                        _context.siger_project_kpi_tasklist.Update(Record);
                        _context.SaveChanges();
                    }
                    else
                    {
                        _context.siger_project_kpi_tasklist.Add(new SigerProjectKpiTasklist
                        {
                            projectId = projectId,
                            Busidate = currDate,
                            ItemId = r.Item,
                            cycle = cycleText,
                            TargetVal = itemObj.TargetVal,
                            ActVal = ratePercent,
                            Section = r.Section,
                            Type = typeResult,
                            Excption = excption,
                            Result = taskResult,
                            Remark = "自动关联"
                    });
                        _context.SaveChanges();
                    }
                }
            }catch(Exception e)
            {
                Logger.WriteLineError(e.StackTrace);
            }
        }
        /// <summary>
        /// 获取关联配置
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<SigerProjectKpiIAutoCalculation>Getlist(int projectId)
        {
            var result = new List<SigerProjectKpiIAutoCalculation>();
            var relationCfg = _context.siger_project_kpi_auto_calculation.Where(f => f.projectId == projectId && f.status==(int)RowState.Valid).ToList();
            //var success = DateTime.TryParse(DateTime.Now.ToShortDateString() + " 8:00", out DateTime dt);
            //foreach (var r in relationCfg)
            //{
            //    if (r.Interval == (int)KpiAutoRelationInterval.Day)
            //    {
            //        var seconds = DateTime.Now.Subtract(dt).TotalSeconds;
            //        if (seconds >= 0 && seconds < 300)
            //        {
            //            result.Add(r);
            //        }
            //    }
            //}
            return relationCfg;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ActVal"></param>
        /// <param name="TargetVal"></param>
        /// <param name="itemObj"></param>
        /// <returns></returns>
        public int GetState(double ActVal, double TargetVal, siger_project_kpi_item itemObj)
        {
            var state = (int)KpiTaskResult.NoConfg;

            switch (itemObj.Condition)
            {
                case (int)KpiCondition.Large:
                    {
                        if (ActVal > TargetVal)
                            state = (int)KpiTaskResult.Normal;
                        else
                            state = (int)KpiTaskResult.Exception;

                        break;
                    }
                case (int)KpiCondition.Less:
                    {
                        if (ActVal < TargetVal)
                            state = (int)KpiTaskResult.Normal;
                        else
                            state = (int)KpiTaskResult.Exception;

                        break;
                    }
                case (int)KpiCondition.LargeEq:
                    {
                        if (ActVal >= TargetVal)
                            state = (int)KpiTaskResult.Normal;
                        else
                            state = (int)KpiTaskResult.Exception;

                        break;
                    }
                case (int)KpiCondition.LessEq:
                    {
                        if (ActVal <= TargetVal)
                            state = (int)KpiTaskResult.Normal;
                        else
                            state = (int)KpiTaskResult.Exception;

                        break;
                    }

            }
            return state;
        }

        /// <summary>
        /// 取产线 /通道
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public List<int>GetLine(int projectId,int parentId)
        {
            var result = new List<int> { parentId };

            var linelevel = _configcontext.siger_project_level.Where(f => f.projectid == projectId && f.status == (int)RowState.Valid).OrderByDescending(o => o.id).ToList();
            if (!linelevel.Any() || linelevel.Count < 2)
                return result;
            var lineSetion = _configcontext.siger_project_level_section.Where(f => f.projectid == projectId && f.levelid == linelevel[1].id && f.parentid==parentId && f.status == (int)RowState.Valid);
            if (lineSetion.Any())
            {
                result.AddRange(lineSetion.Select(s => s.id));
            }
            return result;
        }
    }
}
