using Hotline.Caching.Interfaces;
using Hotline.Share.Dtos.Settings;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Settings;
using MapsterMapper;
using System.ComponentModel;
using XF.Domain.Constants;
using XF.Domain.Dependency;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using XF.Utility.EnumExtensions;
using Hotline.Settings.TimeLimitDomain;

namespace Hotline.Settings.TimeLimits
{
    public class TimeLimitDomainService : ITimeLimitDomainService, IScopeDependency
    {
        private readonly ITimeLimitRepository _timeLimitRepository;
        private List<CalcTimeSetting> timeSettingList;
        private readonly IRepository<SystemSetting> _systemSettingRepository;
        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
        private readonly IMapper _mapper;
        private List<CalcTimeSetting> sourceSettingList;
        private readonly IDaySettingCacheManager _daySettingCacheManager;

        public TimeLimitDomainService(ITimeLimitRepository timeLimitRepository,
            IRepository<SystemSetting> systemSettingRepository, ISystemSettingCacheManager systemSettingCacheManager,
            IMapper mapper, IDaySettingCacheManager daySettingCacheManager)
        {
            _timeLimitRepository = timeLimitRepository;
            _systemSettingRepository = systemSettingRepository;
            _systemSettingCacheManager = systemSettingCacheManager;
            _mapper = mapper;
            _daySettingCacheManager = daySettingCacheManager;

            //初始化常量TODO
            timeSettingList = new List<CalcTimeSetting>();
            CalcTimeSetting setting1 = new CalcTimeSetting() { BusCode = "10", BusName = "咨询", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne =50};
            timeSettingList.Add(setting1);
            CalcTimeSetting setting2 = new CalcTimeSetting() { BusCode = "30", BusName = "举报", TimeType = ETimeType.WorkDay, TimeValue = 5, Percentage = 80 , PercentageOne  = 50};
            timeSettingList.Add(setting2);
            CalcTimeSetting setting3 = new CalcTimeSetting() { BusCode = "35", BusName = "投诉", TimeType = ETimeType.WorkDay, TimeValue = 5, Percentage = 80 , PercentageOne =50 };
            timeSettingList.Add(setting3);
            CalcTimeSetting setting4 = new CalcTimeSetting() { BusCode = "20", BusName = "求助", TimeType = ETimeType.WorkDay, TimeValue = 5, Percentage = 80 , PercentageOne =50 };
            timeSettingList.Add(setting4);
            CalcTimeSetting setting5 = new CalcTimeSetting() { BusCode = "15", BusName = "建议", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne = 50 };
            timeSettingList.Add(setting5);
            CalcTimeSetting setting6 = new CalcTimeSetting() { BusCode = "1", BusName = "意见", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne = 50 };
            timeSettingList.Add(setting6);
            CalcTimeSetting setting7 = new CalcTimeSetting() { BusCode = "2", BusName = "惠民帮助", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 ,PercentageOne = 50 };
            timeSettingList.Add(setting7);
            //CalcTimeSetting setting8 = new CalcTimeSetting() { BugCode = "3", BusName = "大气污染举报", TimeType = ETimeType.WorkDay, TimeValue = 5 };
            //timeSettingList.Add(setting8);
            CalcTimeSetting setting9 = new CalcTimeSetting() { BusCode = "25", BusName = "表扬", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 ,PercentageOne = 50 };
            timeSettingList.Add(setting9);
            CalcTimeSetting setting10 = new CalcTimeSetting() { BusCode = "40", BusName = "其他", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne = 50 };
            timeSettingList.Add(setting10);
        }


        ///// <summary>
        ///// 获取办理时限配置
        ///// </summary>
        ///// <param name="code"></param>
        ///// <param name="iscanter"></param>
        ///// <returns></returns>
        //public int GetOrderTimeLimitConfig(string? code)
        //{
        //    if (string.IsNullOrEmpty(code))
        //    {
        //        return int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.BackCenterTimeSetting).SettingValue[0]);
        //    }
        //    else
        //    {
        //        return timeSettingList.FirstOrDefault(x => x.BugCode == code)?.TimeValue ?? 3;
        //    }
        //}

        /// <summary>
        /// 获取办理时限配置
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.GetOrderTimeLimitConfig"/>IExpireTime.GetOrderTimeLimitConfig
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.GetOrderTimeLimitConfig")]
        public TimeConfig GetOrderTimeLimitConfig(string? code = null)
        {
            if (string.IsNullOrEmpty(code))
            {
                return new TimeConfig(
                    int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.BackCenterTimeSetting).SettingValue[0]),
                    ETimeType.WorkDay);
            }
            else
            {
                var timeSetting = timeSettingList.FirstOrDefault(x => x.BusCode == code);
                return new TimeConfig(timeSetting.TimeValue, timeSetting.TimeType);
            }
        }


        public async Task<string> AddAsync(TimeLimit model, CancellationToken cancellationToken)
        {
            return await _timeLimitRepository.AddAsync(model, cancellationToken);
        }

        public async Task UpdateAsync(TimeLimit model, CancellationToken cancellationToken)
        {
            var dbModel = await _timeLimitRepository.GetAsync(model.Id, cancellationToken);
            if (dbModel == null)
            {
                throw new UserFriendlyException("无效数据");
            }
            await _timeLimitRepository.UpdateAsync(model, cancellationToken);
        }

        /// <summary>
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcEndTime"/>IExpireTime.CalcEndTime
        /// </summary>
        /// <param name="flowDirection"></param>
        /// <param name="Percentage"></param>
        /// <param name="PercentageOne"></param>
        /// <param name="timeType"></param>
        /// <param name="timeValue"></param>
        /// <returns></returns>
        /// <exception cref="UserFriendlyException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        [Obsolete("新的方法 -> IExpireTime.CalcEndTime")]
        public TimeResult? CalcEndTime(EFlowDirection flowDirection, int Percentage,int PercentageOne, ETimeType? timeType = null, int? timeValue = null)
        {
            switch (flowDirection)
            {
                case EFlowDirection.CenterToOrg:
                    if (!timeType.HasValue || !timeValue.HasValue)
                        throw new UserFriendlyException("无效参数");
                    return CalcEndTime(DateTime.Now, timeType.Value, timeValue.Value,Percentage,PercentageOne);
                case EFlowDirection.OrgToCenter:
                    //todo 根据配置
                    return CalcEndTime(DateTime.Now, ETimeType.Day, 1, Percentage,PercentageOne);
                default:
                    throw new ArgumentOutOfRangeException(nameof(flowDirection), flowDirection, null);
            }
        }

        /// <summary>
        /// 计算期满时间
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcExpiredTime"/>IExpireTime.CalcExpiredTime
        /// </summary>
        [Obsolete("新的方法 -> IExpireTime.CalcExpiredTime")]
        public ExpiredTimeWithConfig CalcExpiredTime(DateTime beginTime, EFlowDirection flowDirection, string? acceptTypeCode)
        {
            if (flowDirection is EFlowDirection.CenterToOrg && string.IsNullOrEmpty(acceptTypeCode))
                throw new UserFriendlyException("中心派至部门的工单期满时间需受理类型参数");
            var timeConfig = flowDirection switch
            {
                EFlowDirection.CenterToOrg => GetOrderTimeLimitConfig(acceptTypeCode),
                EFlowDirection.OrgToCenter => GetOrderTimeLimitConfig(),
                EFlowDirection.CenterToCenter => new TimeConfig(1, ETimeType.WorkDay),
				_ => throw new ArgumentOutOfRangeException(nameof(flowDirection), flowDirection, null)
            };

            return CalcEndTime(beginTime, timeConfig, acceptTypeCode);
        }

        /// <summary>
        /// 计算工作时间天数
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTimeToDecimal"/>IExpireTime.CalcWorkTimeToDecimal
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="isCenter"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.CalcWorkTimeToDecimal")]
        public decimal CalcWorkTimeToDecimal(DateTime beginTime,DateTime endTime,bool isCenter)
        {
            var min = CalcWorkTime(beginTime, endTime, isCenter);
            if (min!=0)
            {
                if (isCenter)
                {
                    return Math.Round((decimal)min / 60 / 60 / 24, 2);
                }
                else
                {
                    var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
                    if (workTime != null)
                    {
                        DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                        DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");

                        TimeSpan minuteSpan = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
                        //总时差分钟数
                        int minutes = (int)minuteSpan.TotalMinutes;

                        return Math.Round(((decimal)min/60) / minutes, 2);
                    }
                    return 0;
                }
            }
            return 0;

        }

        /// <summary>
        /// 计算工作时间小时
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTimeToHour"/>IExpireTime.CalcWorkTimeToHour
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="isCenter"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.CalcWorkTimeToHour")]
        public decimal CalcWorkTimeToHour(DateTime beginTime, DateTime endTime, bool isCenter)
        {
	        var min = CalcWorkTime(beginTime, endTime, isCenter);
	        if (min != 0)
	        {
		        if (isCenter)
		        {
			        return Math.Round((decimal)min / 60 / 60 / 24, 2);
		        }
		        else
		        {
			        var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
			        if (workTime != null)
			        {
				        //DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
				        //DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");

				        //TimeSpan minuteSpan = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
				        ////总时差分钟数
				        //int minutes = (int)minuteSpan.TotalMinutes;

				        return Math.Round((decimal)min / 60 / 60 , 2);
			        }
			        return 0;
		        }
	        }
	        return 0;

        }


        /// <summary>
        /// 计算工作时间分钟数（已改返回秒）
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTime"/>IExpireTime.CalcWorkTimeToHour
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="isCenter"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.CalcWorkTime")]
		public int CalcWorkTime(DateTime beginTime, DateTime endTime, bool isCenter)
        {
            if (isCenter)
            {
                //如果是中心，采用中心计算方式
                //计算时间差
                TimeSpan minuteSpan = new TimeSpan(endTime.Ticks - beginTime.Ticks);
                //总时差分钟数
                int minutes = (int)minuteSpan.TotalMinutes;


                //计算开始时间是否计算在工作时间内
                if (!IsWorkDay(beginTime))
                {
                    var newBeginTime = beginTime.AddDays(1).Date;
                    TimeSpan beginTimeMinuteSpan = new TimeSpan(newBeginTime.Ticks - beginTime.Ticks);
                    int beginTimeMinute = (int)beginTimeMinuteSpan.TotalMinutes;
                    minutes = minutes - beginTimeMinute;
                }


                //计算结束时间是否计算在工作时间内
                if (!IsWorkDay(endTime))
                {
                    var newEndTime = endTime.Date;
                    TimeSpan endTimeMinuteSpan = new TimeSpan(endTime.Ticks - newEndTime.Ticks);
                    int endTimeMinute = (int)endTimeMinuteSpan.TotalMinutes;
                    minutes = minutes - endTimeMinute;
                }

                //计算整天时间是否在工作时间内
                int days = minuteSpan.Days;
                for (int i = 0; i < days; i++)
                {
                    var newDay = beginTime.AddDays(i + 1);
                    if (newDay.Date == endTime.Date)
                    {
                        continue;
                    }

                    if (!IsWorkDay(beginTime.AddDays(i + 1)))
                    {
                        minutes = minutes - 1440;
                    }
                }
                return minutes==0 ? 1: minutes*60;
            }
            else
            {
                //如果不是中心（则是部门计算方式）
                //
                var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
                if (workTime != null)
                {
                    //DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                    //DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
                    DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                    DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");

                    //处理开始时间
                    if (beginTime.Date == WorkBeginTime.Date && beginTime < WorkBeginTime)
                    {
                        beginTime = WorkBeginTime;
                    }
                    else
                    {
                        if (beginTime > WorkEndTime)
                        {
                            beginTime = WorkBeginTime.AddDays(1);
                        }
                    }
                    if (beginTime>=endTime)
                    {
                        return 1;
                    }

                    if (endTime.Date == WorkEndTime.Date && endTime < WorkBeginTime)
                    {
                        endTime = WorkBeginTime;
                    }
                    else
                    {
                        if (endTime> WorkEndTime && endTime < WorkBeginTime.AddDays(1))
                        {
                            endTime = WorkBeginTime.AddDays(1);
                        }
                    }

                    while (true)
                    {
                        if (!IsWorkDay(endTime))
                        {
                            endTime = DateTime.Parse(endTime.AddDays(1).ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                        }
                        else
                        {
                            break;
                        }
                    }

                    int minutes = 0;
                    int i = 0;
                    while (true)
                    {
                        i++;
                        //如果是工作日
                        if (IsWorkDay(beginTime))
                        {
                            //最后一天
                            if (beginTime.Date == endTime.Date)
                            {
                                if (endTime > WorkEndTime)
                                {
                                    if (i != 1)
                                    {
                                        TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                    }
                                    else
                                    {
                                        TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - beginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                    }
                                }
                                else
                                {
                                    if (i != 1)
                                    {
                                        TimeSpan sp = new TimeSpan(endTime.Ticks - WorkBeginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                    }
                                    else
                                    {
                                        TimeSpan sp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                    }
                                }
                                return minutes == 0 ? 1 : minutes*60;
                            }
                            //如果不是当天完成
                            else
                            {
                                if (i == 1)
                                {
                                    TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - beginTime.Ticks);
                                    minutes += (int)sp.TotalMinutes;
                                }
                                else
                                {
                                    if (endTime.Date == WorkEndTime.Date)
                                    {
                                        if (endTime > WorkEndTime)
                                        {
                                            TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
                                            minutes += (int)sp.TotalMinutes;
                                        }
                                        else
                                        {
                                            TimeSpan sp = new TimeSpan(endTime.Ticks - WorkBeginTime.Ticks);
                                            minutes += (int)sp.TotalMinutes;
                                        }
                                        return minutes == 0 ? 1 : minutes * 60;
                                    }
                                    else
                                    {
                                        TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                    }
                                }
                            }
                        }

                        beginTime = beginTime.AddDays(1);
                        WorkEndTime = WorkEndTime.AddDays(1);
                        WorkBeginTime = WorkBeginTime.AddDays(1);
                    }
                }
                return 0;
            }
        }


        /// <summary>
        /// 计算工作时间分钟数(已改返回秒)
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTimeEx"/>IExpireTime.CalcWorkTimeEx
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="isCenter"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.CalcWorkTimeEx")] 
        public int CalcWorkTimeEx(DateTime beginTime, DateTime endTime, bool isCenter)
        {
            if (isCenter)
            {
                //如果是中心，采用中心计算方式
                //计算时间差
                TimeSpan minuteSpan = new TimeSpan(endTime.Ticks - beginTime.Ticks);
                //总时差分钟数
                int minutes = (int)minuteSpan.TotalMinutes;


                //计算开始时间是否计算在工作时间内
                if (!IsWorkDay(beginTime))
                {
                    var newBeginTime = beginTime.AddDays(1).Date;
                    TimeSpan beginTimeMinuteSpan = new TimeSpan(newBeginTime.Ticks - beginTime.Ticks);
                    int beginTimeMinute = (int)beginTimeMinuteSpan.TotalMinutes;
                    minutes = minutes - beginTimeMinute;
                }


                //计算结束时间是否计算在工作时间内
                if (!IsWorkDay(endTime))
                {
                    var newEndTime = endTime.Date;
                    TimeSpan endTimeMinuteSpan = new TimeSpan(endTime.Ticks - newEndTime.Ticks);
                    int endTimeMinute = (int)endTimeMinuteSpan.TotalMinutes;
                    minutes = minutes - endTimeMinute;
                }

                //计算整天时间是否在工作时间内
                int days = minuteSpan.Days;
                for (int i = 0; i < days; i++)
                {
                    var newDay = beginTime.AddDays(i + 1);
                    if (newDay.Date == endTime.Date)
                    {
                        continue;
                    }

                    if (!IsWorkDay(beginTime.AddDays(i + 1)))
                    {
                        minutes = minutes - 1440;
                    }
                }
                return minutes == 0 ? 1 : minutes * 60;
            }
            else
            {
                //如果不是中心（则是部门计算方式）
                //
                var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTimeOrg);
                if (workTime != null)
                {
                    //DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                    //DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
                    DateTime MornWorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                    DateTime MornWorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
                    DateTime AfterWorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[2] + ":00");
                    DateTime AfterWorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[3] + ":00");

                    //处理开始时间
                    if (beginTime.Date == MornWorkBeginTime.Date && beginTime < MornWorkBeginTime)
                    {
                        beginTime = MornWorkBeginTime;
                    }
                    else if(beginTime.Date == MornWorkBeginTime.Date && beginTime > MornWorkEndTime && beginTime< AfterWorkBeginTime)
                    {
                        beginTime = AfterWorkBeginTime;
                    }
                    else
                    {
                        if (beginTime > AfterWorkEndTime)
                        {
                            beginTime = MornWorkBeginTime.AddDays(1);
                            MornWorkBeginTime = MornWorkBeginTime.AddDays(1);
                            MornWorkEndTime = MornWorkEndTime.AddDays(1);
                            AfterWorkBeginTime = AfterWorkBeginTime.AddDays(1);
                            AfterWorkEndTime = AfterWorkEndTime.AddDays(1);
                        }
                    }
                    if (beginTime >= endTime)
                    {
                        return 1;
                    }

                    if (endTime.Date == AfterWorkEndTime.Date && endTime < MornWorkBeginTime)
                    {
                        endTime = MornWorkBeginTime;
                    }
                    else if(endTime.Date == AfterWorkEndTime.Date && endTime> MornWorkEndTime && endTime< AfterWorkBeginTime)
                    {
                        endTime = MornWorkEndTime;
                    }
                    else
                    {
                        if (endTime > AfterWorkEndTime && endTime < MornWorkBeginTime.AddDays(1))
                        {
                            endTime = AfterWorkEndTime;//MornWorkBeginTime.AddDays(1);
                        }
                    }

                    while (true)
                    {
                        if (!IsWorkDay(endTime))
                        {
                            endTime = DateTime.Parse(endTime.AddDays(1).ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                        }
                        else
                        {
                            break;
                        }
                    }

                    //计算午休时差
                    var restMinutes = 0;
                    TimeSpan restSp = new TimeSpan(AfterWorkBeginTime.Ticks - MornWorkEndTime.Ticks);
                    restMinutes = (int)restSp.TotalMinutes;


                    int minutes = 0;
                    int i = 0;
                    while (true)
                    {
                        i++;
                        //如果是工作日
                        if (IsWorkDay(beginTime))
                        {
                            //最后一天
                            if (beginTime.Date == endTime.Date)
                            {
                                if (endTime > AfterWorkEndTime)
                                {
                                    if (i != 1)
                                    {
                                        TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - MornWorkBeginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes- restMinutes;
                                    }
                                    //最后一天就是当天
                                    else
                                    {
                                        TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - beginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                        if (beginTime>MornWorkEndTime)
                                        {
                                            minutes = minutes - restMinutes;
                                        }
                                    }
                                }
                                else
                                {
                                    if (i != 1)
                                    {
                                        TimeSpan sp = new TimeSpan(endTime.Ticks - MornWorkBeginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                        if (endTime>AfterWorkBeginTime)
                                        {
                                            minutes = minutes - restMinutes;
                                        }
                                    }
                                    else
                                    {
                                        TimeSpan sp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes;
                                        if (endTime> AfterWorkBeginTime && beginTime< MornWorkEndTime )
                                        {
                                            minutes = minutes - restMinutes;
                                        }
                                    }
                                }
                                return minutes == 0 ? 1 : minutes * 60;
                            }
                            //如果不是当天完成
                            else
                            {
                                if (i == 1)
                                {
                                    TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - beginTime.Ticks);
                                    minutes += (int)sp.TotalMinutes;
                                    if (beginTime>MornWorkEndTime)
                                    {
                                        minutes = minutes - restMinutes;
                                    }
                                }
                                else
                                {
                                    if (endTime.Date == AfterWorkEndTime.Date)
                                    {
                                        if (endTime > AfterWorkEndTime)
                                        {
                                            TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - MornWorkBeginTime.Ticks);
                                            minutes += (int)sp.TotalMinutes - restMinutes;
                                        }
                                        else
                                        {
                                            TimeSpan sp = new TimeSpan(endTime.Ticks - MornWorkBeginTime.Ticks);
                                            minutes += (int)sp.TotalMinutes;
                                            if (endTime> AfterWorkBeginTime)
                                            {
                                                minutes = minutes - restMinutes;
                                            }
                                        }
                                        return minutes == 0 ? 1 : minutes * 60;
                                    }
                                    else
                                    {
                                        TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - MornWorkBeginTime.Ticks);
                                        minutes += (int)sp.TotalMinutes-restMinutes;
                                    }
                                }
                            }
                        }

                        beginTime = beginTime.AddDays(1);
                        AfterWorkEndTime = AfterWorkEndTime.AddDays(1);
                        MornWorkBeginTime = MornWorkBeginTime.AddDays(1);
                        MornWorkEndTime = MornWorkEndTime.AddDays(1);
                        AfterWorkBeginTime = AfterWorkBeginTime.AddDays(1);
                    }
                }
                return 0;
            }
        }

        /// <summary>
        /// 计算工作日
        /// 2024-08-28 过期了,不再使用和维护;
        /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcEndTime"/>IExpireTime.CalcEndTime
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="busCode"></param>
        /// <param name="isCenter"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.CalcEndTime")]
        public ExpiredTimeWithConfig? CalcEndTime(DateTime beginTime, string busCode)
        {
            var setting = timeSettingList.FirstOrDefault(x => x.BusCode == busCode);
            if (setting != null)
            {
                var result =  CalcEndTime(beginTime, setting.TimeType, setting.TimeValue, setting.Percentage, setting.PercentageOne);
                var expiredTimeWithConfig = new ExpiredTimeWithConfig();
                expiredTimeWithConfig.TimeText = setting.TimeValue+"个"+setting.TimeType.GetDescription();
                expiredTimeWithConfig.TimeType = setting.TimeType;
                expiredTimeWithConfig.Count = setting.TimeValue;
                expiredTimeWithConfig.ExpiredTime = result.EndTime;
                expiredTimeWithConfig.NearlyExpiredTime = result.NearlyExpiredTime;
                expiredTimeWithConfig.NearlyExpiredTimeOne = result.NearlyExpiredTimeOne;
                return expiredTimeWithConfig;
            }
            return null;
        }

        public ExpiredTimeWithConfig CalcEndTime(DateTime beginTime, TimeConfig timeConfig,string busCode)
        {
            var setting = timeSettingList.FirstOrDefault(x => x.BusCode == busCode);
            if (setting!=null)
            {
                var result = CalcEndTime(beginTime, timeConfig.TimeType, timeConfig.Count, setting.Percentage,setting.PercentageOne);
                var expiredTimeWithConfig = _mapper.Map<ExpiredTimeWithConfig>(timeConfig);
                expiredTimeWithConfig.ExpiredTime = result.EndTime;
                expiredTimeWithConfig.NearlyExpiredTime = result.NearlyExpiredTime;
                expiredTimeWithConfig.NearlyExpiredTimeOne = result.NearlyExpiredTimeOne;
                return expiredTimeWithConfig;
            }
            return null;
        }


        public TimeResult CalcEndTime(DateTime beginTime, ETimeType timeType, int timeValue, string busCode)
        {
            var setting = timeSettingList.FirstOrDefault(x => x.BusCode == busCode);
            if (setting!=null)
            {
                var result = CalcEndTime(beginTime, timeType, timeValue, setting.Percentage,setting.PercentageOne);
                return result;
            }
            return null;
        }

        /// <summary>
        /// 计算工作日
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="timeType"></param>
        /// <param name="timeValue"></param>
        /// <param name="Percentage">即将超期百分比</param>
        /// <param name="PercentageOne">超期百分比第一级</param>
        /// <returns></returns>
        public TimeResult CalcEndTime(DateTime beginTime, ETimeType timeType, int timeValue,int Percentage,int PercentageOne)
        {
            DateTime startTime = beginTime;
            DateTime startTimeOne = beginTime;
            //如果是部门，采用部门计算方式
            switch (timeType)
            {
                #region 小时计算
                //新增对应小时
                //case ETimeType.Hour:
                //if (isCenter)
                //{
                //    //中心计算自然时间
                //    return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
                //}
                //else
                //{
                //    //部门计算工作时间
                //    //查询统一部门工作时间
                //    var workTime = _systemSettingRepository.Get(x => x.Code == "WorkTime");
                //    if (workTime != null)
                //    {
                //        //计算一天工作时间（分钟）
                //        DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                //        DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
                //        TimeSpan minuteSpan = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
                //        //一天工作时间（分钟）
                //        int minutes = (int)minuteSpan.TotalMinutes;
                //        //延期总时间（分钟）
                //        int timeValueMinutes = timeValue * 60;

                //        //判断开始时间不在工时间段修正时间复位至当天或者第二天的开始时间（如果大于结束时间则复位至第二天的开始时间）
                //        if (beginTime < WorkBeginTime)
                //        {
                //            beginTime = WorkBeginTime;
                //        }
                //        else
                //        {
                //            if (beginTime > WorkEndTime)
                //            {
                //                beginTime = WorkBeginTime.AddDays(1);
                //            }
                //        }

                //        //判断第一天时间是否足够
                //        TimeSpan firstMinuteSpan = new TimeSpan(WorkEndTime.Ticks - beginTime.Ticks);
                //        //计算开始时间的第一天时间
                //        int firstMinute = (int)firstMinuteSpan.TotalMinutes;
                //        //判断第一天时间是否足够
                //        if (firstMinute > timeValueMinutes)
                //        {
                //            //足够
                //            bool canWhile = true;
                //            while (canWhile)
                //            {
                //                //判断开始时间是否在工作日
                //                if (IsWorkDay(beginTime))
                //                {
                //                    return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
                //                }
                //                else
                //                {
                //                    //如果不是工作日就加一天
                //                    beginTime = beginTime.AddDays(1);
                //                }
                //            }
                //            return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
                //        }
                //        else
                //        {
                //            //不够
                //            bool canWhile = true;
                //            while (canWhile)
                //            {
                //                //判断开始时间是否在工作日
                //                if (IsWorkDay(beginTime))
                //                {
                //                    //在工作日
                //                    timeValueMinutes = timeValueMinutes - minutes;
                //                    if (timeValueMinutes > 0)
                //                    {
                //                        beginTime = beginTime.AddDays(1);
                //                    }
                //                    else
                //                    {
                //                        return new TimeResult { EndTime = beginTime.AddMinutes(timeValueMinutes), RuleStr = timeValue + "小时" };
                //                    }
                //                }
                //                else
                //                {
                //                    //如果不是工作日
                //                    beginTime = beginTime.AddDays(1);
                //                }
                //            }
                //        }

                //    }
                //    return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
                //}
                //   return null;
                #endregion
                //新增工作日
                case ETimeType.WorkDay:

                    //检查时间段内是否存在休息日或者工作日
                    //查询统一部门工作时间
                    var workTimeWorkDay = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
                    if (workTimeWorkDay != null)
                    {
                        //计算一天工作时间（分钟）
                        DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[0] + ":00");
                        DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00");
                        //计算一天多少个工作小时
                        var duration =  WorkEndTime - WorkBeginTime;
                        double workMinutes = duration.TotalMinutes;
                        double totalWorkMinutes = (workMinutes * timeValue) * (Percentage/100.00);
                        double totalWorkMinutesOne = (workMinutes * timeValue) * (PercentageOne / 100.00);

                        //判断开始时间不在工时间段修正时间复位至当天或者第二天的开始时间（如果大于结束时间则复位至第二天的开始时间）
                        
                        if (beginTime < WorkBeginTime)
                        {
                            beginTime = WorkBeginTime;
                        }
                        else
                        {
                            if (beginTime > WorkEndTime)
                            {
                                beginTime = WorkBeginTime.AddDays(1);
                            }
                            if (!IsWorkDay(beginTime))
                            {
                                beginTime = WorkBeginTime.AddDays(1);
                            }
                        }

                        while (true)
                        {
                            if (IsWorkDay(beginTime))
                            {
                                break;
                            }
                            beginTime = beginTime.AddDays(1);
                            WorkBeginTime = WorkBeginTime.AddDays(1);
                            WorkEndTime = WorkEndTime.AddDays(1);
                        }

                        int day = 1;
                        for (int i = 1; i < timeValue + 1; i++)
                        {
                            if (IsWorkDay(beginTime.AddDays(day)))
                            {
                                beginTime = beginTime.AddDays(day);
                                
                                if (totalWorkMinutes >= workMinutes)
                                {
                                    startTime = startTime.AddDays(day);
                                    totalWorkMinutes = totalWorkMinutes - workMinutes;
                                }
                                else if(totalWorkMinutes < workMinutes && totalWorkMinutes != 0)
                                {
                                    if (startTime.AddMinutes(totalWorkMinutes)> DateTime.Parse(startTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00"))
                                    {
                                        totalWorkMinutes = totalWorkMinutes - ((DateTime.Parse(startTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00") - startTime).TotalMinutes);
                                        startTime = startTime.AddDays(day);
                                        startTime = DateTime.Parse(startTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[0] + ":00").AddMinutes(totalWorkMinutes);
                                        totalWorkMinutes = 0;
                                    }
                                    else
                                    {
                                        startTime = startTime.AddMinutes(totalWorkMinutes);
                                    }
                                }

                                if (totalWorkMinutesOne >= workMinutes)
                                {
                                    startTimeOne = startTimeOne.AddDays(day);
                                    totalWorkMinutesOne = totalWorkMinutesOne - workMinutes;
                                }
                                else if(totalWorkMinutesOne < workMinutes && totalWorkMinutesOne!=0)
                                {
                                    if (startTimeOne.AddMinutes(totalWorkMinutesOne)> DateTime.Parse(startTimeOne.ToShortDateString()+" "+ workTimeWorkDay.SettingValue[1]+":00"))
                                    {
                                        totalWorkMinutesOne = totalWorkMinutesOne - ((DateTime.Parse(startTimeOne.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00") - startTimeOne).TotalMinutes);
                                        startTimeOne = startTimeOne.AddDays(day);
                                        startTimeOne = DateTime.Parse(startTimeOne.ToShortDateString() + " " + workTimeWorkDay.SettingValue[0] + ":00").AddMinutes(totalWorkMinutesOne);
                                        totalWorkMinutesOne = 0;
                                    }
                                    else
                                    {
                                        startTimeOne = startTimeOne.AddMinutes(totalWorkMinutesOne);
                                    }
                                }


                                day = 1;
                            }
                            else
                            {
                                i--;
                                day++;
                            }
                        }
                    }


                    //TimeSpan duration = beginTime - startTime;
                    //double percentage = 0.8 * duration.TotalHours;
                    //DateTime resultTime = startTime + TimeSpan.FromHours((int)(percentage));
                    //bool isWhile = true;
                    //while (isWhile)
                    //{
                    //    if (IsWorkDay(resultTime))
                    //    {
                    //        isWhile = false;
                    //    }
                    //    else
                    //    {
                    //        resultTime = resultTime.AddDays(1);
                    //    }
                    //}


                    return new TimeResult { EndTime = beginTime, RuleStr = timeValue + "个工作日", NearlyExpiredTime = startTime , NearlyExpiredTimeOne = startTimeOne };
                //新增自然日
                case ETimeType.Day:
                    return new TimeResult { EndTime = beginTime.AddDays(timeValue), RuleStr = timeValue + "个自然日", NearlyExpiredTime = beginTime.AddDays(timeValue*(Percentage/(double)100)), NearlyExpiredTimeOne = beginTime.AddDays(timeValue*(PercentageOne/(double)100)) };
                default:
                    return null;
            }
        }

        /// <summary>
        /// 计算时间间隔
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="isCenter"></param>
        /// <returns></returns>
        public string CalcTimeInterval(DateTime beginTime, DateTime endTime, bool isCenter)
        {
            if (isCenter)
            {
                //如果是中心按24小时制
                TimeSpan centerIntervalSp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
                double re = Math.Round(((double)centerIntervalSp.Microseconds / (24 * 60)), 1);
                if (re > 0)
                {
                    return re + "天后超期";
                }
                else
                {
                    return "已超期" + Math.Abs(re) + "天";
                }
            }
            else
            {
                //如果是部门按工作时间 8小时制
                TimeSpan centerIntervalSp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
                double re = Math.Round(((double)centerIntervalSp.Microseconds / (8 * 60)), 1);
                if (re > 0)
                {
                    return re + "天后超期";
                }
                else
                {
                    return "已超期" + Math.Abs(re) + "天";
                }
                return "";
            }
        }


        public bool IsWorkDay(DateTime date)
        {
            return _daySettingCacheManager.IsWorkDay(date);
        }

        /// <summary>
        /// 判断当前时间是否是工作日 返回一个工作日
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        [Obsolete("新的方法 -> IExpireTime.WorkDay")]
        public DateTime WorkDay(DateTime date)
        {
            var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
            if (IsWorkDay(date))
            {
                DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
                if (date < WorkBeginTime || date > WorkEndTime)
                {
                    date = DateTime.Parse(date.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
                }
            }
            else {
	            while (!IsWorkDay(date))
	            {
		            date = date.AddDays(1);
	            }
	            DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
	            DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
	            if (date < WorkBeginTime || date > WorkEndTime)
	            {
		            date = DateTime.Parse(date.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
	            }
			}
            return date;
        }

        /// <summary>
        /// 倒推工作日
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        [Obsolete()]
        public DateTime CalcWorkTimeReduce(DateTime date,int timeValue)
        {
            for (int i = 0; i < timeValue; i++)
            {
                if (IsWorkDay(date))
                {
                    date = date.AddDays(-1);
                }
                else
                {
                    date = date.AddDays(-1);
                    i--;
                }
            }

            return date;
        }
    }
}
