using Microsoft.Extensions.Logging;
using PARR.Common;
using PARR.DAL.Contracts;
using PARR.DAL.Services.Interfaces;

namespace PARR.DAL.TransformServices
{
    internal class NextRunModifierService : INextRunModifierService
    {
        private readonly SettingsFromDb settingsFromDb;
        private readonly ILogger<NextRunModifierService> logger;
        private readonly IWeekendDayService weekendDayService;

        public NextRunModifierService(
            SettingsFromDb settingsFromDb,
            ILogger<NextRunModifierService> logger,
            IWeekendDayService weekendDayService
            )
        {
            this.settingsFromDb = settingsFromDb;
            this.logger = logger;
            this.weekendDayService = weekendDayService;
        }


        public DateTimeOffset GetNextRunByAccountRobotTimeZone(DateTimeOffset nextRun)
        {
            return nextRun.AddHours(settingsFromDb.EsppRobotAccountTimeZoneHour);
        }


        public async Task<DateTimeOffset> GetWorkDayAsync(DateTimeOffset nextRun)
        {
            // получаем день относительно часового пояса МСК
            var date = DateOnly.FromDateTime(DateResolver.IsCurrentDayRelativeMskTime(nextRun) ? nextRun.Date : nextRun.Date.AddDays(1));

            if (await weekendDayService.IsWorkDayAsync(date, true))
            {
                //текущий nextRun рабочий день, возвращаем его
                return nextRun;
            }

            // ищем следующий рабочий день, максимум 20 итераций, если за их кол-во не нашли рабочий, берём последний не рабочий
            int count = 20;
            while (count > 0)
            {
                date = date.AddDays(1);
                var isWorkDay = await weekendDayService.IsWorkDayAsync(date, true);
                if (isWorkDay)
                    break; // это рабочий день, выбираем его

                count--;

                if (!isWorkDay && count == 0)
                    logger.LogWarning($"Не нашли рабочий день за 20 итераций, взяли последний нерабочий {date}");
            }

            // смотрим, если смещали из-за пояса МСК на день вперед, вычитаем этот день назад
            if (!DateResolver.IsCurrentDayRelativeMskTime(nextRun))
                date = date.AddDays(-1);

            // считаем новый NextRun
            var dayCount = date.DayNumber - DateOnly.FromDateTime(nextRun.Date).DayNumber;

            return nextRun.AddDays(dayCount);
        }
    }
}
