using System.Collections.Generic;
using System.Linq;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;

namespace Siger.ApiTPM.Utilities
{
    public class PlanReportLevelHelper
    {
        private readonly int _projectId;
        private readonly IPlanReportRepository _planReport;
        public PlanReportLevelHelper(int projectId, IPlanReportRepository planReport)
        {
            _projectId = projectId;
            _planReport = planReport;
        }

        #region 获取超时异常上报的计划维护

        /// <summary>
        /// 获取计划维护上报等级 >1表示已经超时，=1未超时
        /// </summary>
        /// <param name="itemModel">模式 1->AM(自主执行)；2->PM</param>
        /// <param name="time">当前时间</param>
        /// <param name="instructionTime">执行时间</param>
        /// <param name="instructionCycle">执行周期</param>
        /// <param name="configRepeatTime">配置的重复推送时间</param>
        /// <param name="spaceTimeArr"></param>
        /// <returns></returns>
        public int GetPlanReportTimeOut(int itemModel, int time, int instructionTime, int instructionCycle,
            int configRepeatTime, List<siger_project_plan_report> spaceTimeArr)
        {
            var level = 0;
            var days = (float) (time - instructionTime) / 86400;
            if (spaceTimeArr.Any())
            {
                switch (instructionCycle)
                {
                    case 1:
                        level = GetReportLevel(spaceTimeArr, 1, days, configRepeatTime);
                        break;
                    case 7:
                        level = GetReportLevel(spaceTimeArr, 2, days, configRepeatTime);
                        break;
                    case 15:
                        level = GetReportLevel(spaceTimeArr, 3, days, configRepeatTime);
                        break;
                    case 30:
                        level = GetReportLevel(spaceTimeArr, 4, days, configRepeatTime);
                        break;
                    case 60:
                        level = GetReportLevel(spaceTimeArr, 5, days, configRepeatTime);
                        break;
                    case 120:
                        level = GetReportLevel(spaceTimeArr, 6, days, configRepeatTime);
                        break;
                    case 180:
                        level = GetReportLevel(spaceTimeArr, 7, days, configRepeatTime);
                        break;
                    case 360:
                        level = GetReportLevel(spaceTimeArr, 8, days, configRepeatTime);
                        break;
                }
            }

            return level;
        }

        private int GetReportLevel(List<siger_project_plan_report> spaceTimeArr, int type, float difference, int configRepeatTime)
        {
            var spaceTime1 = spaceTimeArr.FirstOrDefault(t => t.type == type && t.start_level == 1);
            if (spaceTime1 != null)
            {
                var spacetime = spaceTime1.space_time;
                if (difference % configRepeatTime < 1 && difference < spacetime && difference >= configRepeatTime)
                {
                    return 1;
                }
            }
            var spaceTime2 = spaceTimeArr.FirstOrDefault(t => t.type == type && t.start_level == 2);
            var spaceTime3 = spaceTimeArr.FirstOrDefault(t => t.type == type && t.start_level == 3);
            if (spaceTime3 != null && spaceTime1 != null && spaceTime2 != null)
            {
                var spacetime3 = spaceTime3.space_time;
                var spacetime2 = spaceTime2.space_time;
                var spacetime1 = spaceTime1.space_time;
                var diff3 = difference - spacetime3;
                var diff2 = difference - spacetime2;
                var diff1 = difference - spacetime1;
                if (diff3 >= 0 && difference % spacetime3 < 1 && diff3 < 1)
                {
                    return 4;
                }
                else if (diff3 >= 0 && diff3 % configRepeatTime < 1 && diff3 >= configRepeatTime)
                {
                    return 4;
                }
                else if (diff2 >= 0 && diff3 < 0 && difference % spacetime2 < 1 && diff2 < 1)
                {
                    return 3;
                }
                else if (diff2 >= 0 && diff3 < 0 && diff2 % configRepeatTime < 1 && diff2 >= configRepeatTime)
                {
                    return 3;
                }
                else if (diff1 >= 0 && diff2 < 0 && difference % spacetime1 < 1 && diff1 < 1)
                {
                    return 2;
                }
                else if (diff1 >= 0 && diff2 < 0 && diff1 % configRepeatTime < 1 && diff1 >= configRepeatTime)
                {
                    return 2;
                }
            }
            return 0;
        }

        private int GetPlanReportTimeOutByType(List<siger_project_plan_report> spaceTimeArr, int type, float days,
            int repeatTime)
        {
            int level = 0;
            var spaceTime = spaceTimeArr.FirstOrDefault(t => t.type == type && t.start_level == 3);
            if (spaceTime != null && days > spaceTime.space_time)
            {
                if (CompareTwo(days, spaceTime.space_time, repeatTime))
                {
                    level = 4;
                }
            }
            else
            {
                spaceTime = spaceTimeArr.FirstOrDefault(t => t.type == type && t.start_level == 2);
                if (spaceTime != null && days > spaceTime.space_time)
                {
                    if (CompareTwo(days, spaceTime.space_time, repeatTime))
                    {
                        level = 3;
                    }
                }
                else
                {
                    spaceTime = spaceTimeArr.FirstOrDefault(t => t.type == type && t.start_level == 1);
                    if (spaceTime != null && days > spaceTime.space_time)
                    {
                        if (CompareTwo(days, spaceTime.space_time, repeatTime))
                        {
                            level = 2;
                        }
                    }
                }
            }

            return level;
        }

        private bool CompareTwo(float difference, int spaceTime, int repeatTime)
        {
            var diff = (difference - spaceTime) % repeatTime;
            return diff < 1;
        }

        #endregion
    }
}
