using PARR.Core.Common.Interfaces;
using PARR.Domain.Cache;
using PARR.Domain.Enums;
using PARR.EsppApi;
using PARR.EsppApi.Constants;
using PARR.EsppApi.Models.Query;
using PARR.Test.NextRun;

namespace PARR.Test
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly IEsppApiService esppApiService;
        private readonly IIntervalService intervalService;
        //private readonly ICalendarService calendarService;
        private readonly IServiceProvider serviceProvider;

        public Worker(
            ILogger<Worker> logger,
            IEsppApiService esppApiService,
            IIntervalService intervalService,
            //ICalendarService calendarService,
            IServiceProvider serviceProvider
            )
        {
            _logger = logger;
            this.esppApiService = esppApiService;
            this.intervalService = intervalService;
            //this.calendarService = calendarService;
            this.serviceProvider = serviceProvider;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            //var aaa = DateTimeOffset.UtcNow;
            //var bbb = aaa.ToOffset(new TimeSpan(3, 0, 0));


            #region NextRunTest

            using (var scope = serviceProvider.CreateScope())
            {
                var service = scope.ServiceProvider.GetService<NextRunTest>();

                await service!.Test();
            }

            #endregion


            #region test
            //using (var scope = serviceProvider.CreateScope())
            //{
            //    var templateService = scope.ServiceProvider.GetService<ITemplateService>();
            //    var shortcodesService = scope.ServiceProvider.GetService<IShortcodesService>();
            //    var robotConfigurationService = scope.ServiceProvider.GetService<IRobotConfigurationService>();


            //    var ts = await templateService.Get().Include(t => t.Job).Where(t => t.ScheduleEsppId != null && t.Name.Contains("ЭИТИ-ПТК-ПАРР") && !t.Name.Contains("!!!")).ToListAsync();

            //    if (!ts.Any())
            //        return;


            //    var jobIds = ts.Select(t => t.JobId).Distinct();
            //    foreach (var template in ts)
            //    {
            //        var isExistSameKeyValueTemplate = await templateService.Get().AsNoTracking().AnyAsync(t => t.JobId == template.JobId && t.UnitId == template.UnitId && t.Name != template.Name);

            //        var templateName = await shortcodesService.ApplyShortcodesAsync(template.Job.TemplateNameMask, template.UnitId, template.JobId);

            //        if (isExistSameKeyValueTemplate)
            //        {
            //            template.IsActiveTemplate = false;
            //            template.IsActiveSchedule = false;
            //            template.Name = string.Concat("!!!", templateName.ToUpper());
            //            template.DateModified = DateTimeOffset.UtcNow;
            //            if (!(await templateService.CommitAsync(template)))
            //                _logger.LogInformation($"Не удалось сохнаить изменения {template.ToString()}");
            //            continue;
            //        }


            //        var oldName = template.Name;
            //        var rt = await robotConfigurationService.Get().FirstOrDefaultAsync(t => t.TemplateId == template.Id);

            //        if (rt != null)
            //        {
            //            template.IsActiveTemplate = true;
            //            template.IsActiveSchedule = false;
            //            template.Name = templateName.ToUpper();
            //            template.DateModified = DateTimeOffset.UtcNow;

            //            robotConfigurationService.ChangeTaskStatus(DAL.Contracts.TaskStatusEnum.Updating, ref rt);
            //            //_logger.LogInformation(templateName);
            //        }

            //        if (!(await templateService.CommitAsync(template)))
            //            _logger.LogInformation($"Не удалось сохранить изменения {template.ToString()}");
            //    }
            //    _logger.LogInformation($"Опа опа опа...");
            //}
            #endregion

            #region unit


            //using (var scope = serviceProvider.CreateScope())
            //{
            //    var service = scope.ServiceProvider.GetService<IUnitService>();


            //    var unit = await service.Get().Include(t => t.Parents).Include(t => t.Childs).FirstOrDefaultAsync(t => t.Id == Guid.Parse("0f89e2ec-0e4d-4de6-b990-c55e8308accf"));

            //    var parent = unit?.Parents;


            //}

            #endregion

            #region Calendar

            //var testCalendar = new BLL.Services.Implementations.Test(calendarService);

            //testCalendar.Ttt() ;
            //using (var scope = serviceProvider.CreateScope())
            //{
            //    var weekendDayService = scope.ServiceProvider.GetService<IWeekendDayService>();

            //    var workDays = calendarService.GetWorkDatesForPeriod(new DateOnly(2024, 07, 01), TimeSpan.Parse("30:00:00:00"), weekendDayService!.GetWeekends);
            //}


            //IDistributionPeriodService

            //using (var scope = serviceProvider.CreateScope())
            //{
            //    var service = scope.ServiceProvider.GetService<ICalendarService>();
            //    var weekEndService = scope.ServiceProvider.GetService<IWeekendDayService>();


            //    var aa = service!.GetWorkDatesForPeriod(new DateOnly(2024, 07, 01), DistributionPeriodTypeEnum.Year, "1", weekEndService!.GetWeekends);

            //    //var aaa = await service!.Get().ToListAsync();

            //    //foreach (var aaaItem in aaa)
            //    //{

            //    //    var bbbb = aaaItem.AddDate;


            //    //    var now = DateTimeOffset.UtcNow;
            //    //    var newwww = now.AddMicroseconds(bbbb.);
            //    //}


            //}


            #endregion


            ////test interval
            //await intervalService.IntervalInitAsync(async () =>
            //{
            //    _logger.LogInformation("---Выполняю метод---"); 
            //    await Task.Delay(29*1000);
            //    _logger.LogInformation("===Выполнил метод===");
            //}, new TimeSpan(0, 0, 30));



            //await TestEsppApi();
            //await StopDiscontinuedOrdersInEspp();
        }


        private async Task TestEsppApi()
        {
            //var result = await esppApiService.FindOrdersAsync(new FindOrdersQuery { DescriptionContains = "Полное", GenerateDateStart = new DateTime(2023, 10, 10) , GenerateDateEnd = new DateTime(2023, 10, 24) });
            var recordId = "НАР24-00009262";

            var result = await esppApiService.FindOrderByRecordIdAsync(recordId);

            if (result.IsSuccess && (result.Data != null && result.Data.Number.Any()))
            {
                //var orders = result.Data;

                //в работу
                var inWorkResult = await esppApiService.SetStatusInWorkAsync(recordId, "Регламентные работы в автоматическом режиме созданы и выполнены;"); //"Решение...\nС новой строки"
                if (!inWorkResult.IsSuccess)
                {
                    _logger.LogError(inWorkResult.Exception, $"Не удалось взять в работу наряд {recordId}");
                    return;
                }

                var tnk = new AddMtnkQuery { RecordId = recordId, JobOperation = "Не учтена в перечне ТНК", Time = "00:05" };

                var addMtnkResult = await esppApiService.AddMTnkAsync(tnk);

                if (!addMtnkResult.IsSuccess)
                {
                    _logger.LogError(addMtnkResult.Exception, $"Не удалось списать трудозатраты наряда {recordId}");
                    return;
                }

                //выполнить
                var resFinish = await esppApiService.SetStatusIsDoneAsync(recordId, "Регламентные работы в автоматическом режиме созданы и выполнены;", EsppOrderClosingCodeEnum.Auto);
                if (!resFinish.IsSuccess)
                {
                    _logger.LogError(resFinish.Exception, $"Не удалось обновить статус наряда {recordId}");
                    return;
                }
            }
            else
            {
                _logger.LogWarning($"не найден наряд {recordId}");
            }
        }


        private async Task StopDiscontinuedOrdersInEspp()
        {
            const string ResultMsg = "Сформирован ошибочно";

            var searchQuery = new FindOrdersQuery
            {
                DescriptionContains = "ЭИТИ-ПТК-ПАРР",
                StatusIs = "1-Направлен в группу",
                GenerateDateStart = new DateTime(2024, 02, 26, 0, 0, 0),
                GenerateDateEnd = new DateTime(2024, 02, 29, 0, 0, 0)
            };
            var result = await esppApiService.FindOrdersAsync(searchQuery);

            if (result.IsSuccess && result.Data != null)
            {
                foreach (var item in result.Data)
                {
                    if (item.StatusEnum == OrderStatusEnum.New)
                    {
                        await esppApiService.SetStatusInWorkAsync(item.Number, ResultMsg);
                    }

                    var newItem = await esppApiService.FindOrderByRecordIdAsync(item.Number);
                    if (newItem.IsSuccess && newItem.Data != null && newItem.Data.StatusEnum == OrderStatusEnum.InWork)
                    {
                        var tnk = new AddMtnkQuery { RecordId = newItem.Data.Number, JobOperation = "Прочее(наряды)", Time = "00:01" };

                        await esppApiService.AddMTnkAsync(tnk);
                        await esppApiService.SetStatusIsDoneAsync(newItem.Data.Number, ResultMsg, EsppOrderClosingCodeEnum.Breake);
                    }
                }
            }
        }
    }

}
