using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.AIHITLoader.Models;
using PARR.AIHITLoader.Services;
using PARR.AIHITLoader.Settings;
using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces;
using System.Globalization;
using System.Text.Json;

namespace PARR.AIHITLoader
{
    internal class AihitLoader : IAihitLoader
    {
        private readonly IIntervalService intervalService;
        private readonly ILogger<AihitLoader> logger;
        private readonly WorkerSettings workerSettings;
        private readonly LoaderSettings loaderSettings;
        private readonly IMqService mqService;
        private readonly MqSettings mqSettings;
        private readonly IServiceProvider serviceProvider;

        public AihitLoader(
            IIntervalService intervalService,
            ILogger<AihitLoader> logger,
            WorkerSettings workerSettings,
            LoaderSettings loaderSettings,
            IMqService mqService,
            MqSettings mqSettings,
            IServiceProvider serviceProvider
            )
        {
            this.intervalService = intervalService;
            this.logger = logger;
            this.workerSettings = workerSettings;
            this.loaderSettings = loaderSettings;
            this.mqService = mqService;
            this.mqSettings = mqSettings;
            this.serviceProvider = serviceProvider;
        }

        public async Task StartAsync()
        {
            logger.LogInformation("Запуск сервиса загрузки данных из АИХИТ.");

            await intervalService.IntervalInitAsync(UploadDataAsync, workerSettings.RepeatEvery);
        }

        private async Task UploadDataAsync()
        {
            foreach (var respArea in loaderSettings.ResponseAreas)
            {
                var aihitData = GetDataFromAihit(respArea);

                if (aihitData == null) return;

                var filteredAIhitData = FilterData(aihitData);

                var preparedData = filteredAIhitData.Select(d => JsonSerializer.Serialize(MapAihitToDomain(d)));

                var parts = preparedData.Count() / loaderSettings.PackageSize;
                parts++;

                for (var i = 0; i < parts; i++)
                {
                    var batch = preparedData.Skip(i * loaderSettings.PackageSize).Take(loaderSettings.PackageSize).ToList();
                    var sendResult = await mqService.SendAsync(mqSettings, batch.ToArray());
                    if (sendResult.IsSuccess)
                    {
                        logger.LogInformation($"Данные переданы в RabbitMQ: {batch.Count()}");
                        logger.LogDebug($"Список ЭК переданных в RabbitMQ: {string.Join(", ", batch)}");
                    }
                    else
                        logger.LogError($"Ошибка при передаче нарядов в Rabbit, не переданные сообщения: {string.Join(", ", sendResult.NotSendMessages!)}");
                }

            }
           // await Task.CompletedTask;
        }

        /// <summary>
        /// Фильтруем входные данные из АИХ ИТ по необходимости. На первом этапе берём только эк по максе ВРТ-*, так же берем ХСТ-*
        /// </summary>
        /// <param name="aihitData"></param>
        /// <returns></returns>
        private List<EK> FilterData(List<EK> aihitData)
        {
            //var vrt = aihitData.Where(ek => ek.EKFindCode!.StartsWith("ВРТ", true, CultureInfo.GetCultureInfo("ru-RU"))).ToList();

            var vrt = aihitData.Where(ek =>
                                        ek.EKFindCode!.StartsWith("ВРТ", true, CultureInfo.GetCultureInfo("ru-RU"))
                                        || ek.EKFindCode!.StartsWith("ХСТ", true, CultureInfo.GetCultureInfo("ru-RU"))
                                    ).ToList();

            //return vrt.Where(vrt => vrt.IP != null).ToList();
            return vrt.ToList();
        }

        private List<EK>? GetDataFromAihit(string respArea)
        {
            using (var scope = serviceProvider.CreateScope())
            {
                var aihitService = scope.ServiceProvider.GetService<IAIHITService>();
                if (aihitService == null)
                    throw new Exception("Не смог получить серивс IAIHITService, scope.ServiceProvider.GetService<IAIHITService>()");

                return aihitService.GetEKList(respArea);
            }
        }


        private AihitDataMq MapAihitToDomain(EK ek)
        {
            return new AihitDataMq
            {
                EK = ek.EKFindCode!,
                IP = ek.IP,
                APP = ek.APPType,
                DB = ek.DBType,
                CKBS = ek.CKBSServerType,
                IB = ek.IBServerType,
                SI = ek.InfrastructureServerType,
                SM = ek.MonitoringServerType,
                OS = ek.OSType,
                WorkGroup = ek.WorkGroup,
                //Status = (ek.Status == "00-ГВЦ") ? "99-ГВЦ" : ek.Status!,
                //ResponseArea = ek.ResponseArea!
                Status = ek.Status!,
                ResponseArea = (ek.ResponseArea == "00-ГВЦ") ? "99-ГВЦ" : ek.ResponseArea!,
                WorkGroupResponseArea = (ek.WorkGroupResponseArea == "00-ГВЦ") ? "99-ГВЦ" : ek.WorkGroupResponseArea!
            };
        }
    }
}
