using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.Core.Common.Interfaces;
using PARR.Core.Common.Interfaces.RabbitServices;
using PARR.Core.Services.TaskServices.Handlers.Factory;
using PARR.Core.Services.Workload.Interfaces;
using PARR.Domain.Common.Rabbit.Messages;
using PARR.Domain.Enums;
using PARR.Domain.Settings;

namespace PARR.Core.Services.Workload.Implementations
{
    internal class WorkloadCacheBuilderService : IWorkloadCacheBuilderService
    {
        private readonly ILogger<WorkloadCacheBuilderService> logger;
        private readonly IRabbitService rabbitService;
        private readonly ITransformService transformService;
        private readonly IServiceProvider serviceProvider;

        public WorkloadCacheBuilderService(
            ILogger<WorkloadCacheBuilderService> logger,
            IRabbitService rabbitService,
            ITransformService transformService,
            IServiceProvider serviceProvider
            )
        {
            this.logger = logger;
            this.rabbitService = rabbitService;
            this.transformService = transformService;
            this.serviceProvider = serviceProvider;
        }


        public async Task ProcessMessagesAsync(IMqSettings mqSettings)
        {
            // этот метод вызывается в воркере

            var isConnected = await rabbitService.InitConsumerAsync(mqSettings, async (msg) =>
            {
                logger.LogInformation($"Получили запрос: {msg}");

                var queueMessage = transformService.GetModelFromJson<TaskMessage>(msg);
                if (queueMessage == null)
                    return;

                // Проверим тип сообщения, что он соответствует текущему сервису
                if (queueMessage.TypeCode != TaskTypeEnum.Workload)
                {
                    logger.LogError("Несоответствие типа: в очереди {Queue} получена задача типа {Actual}", mqSettings.QueueName, queueMessage.TypeCode);
                    return;
                }

                using (var scope = serviceProvider.CreateScope())
                {
                    var handlerFactory = scope.ServiceProvider.GetRequiredService<ITaskHandlerFactory>();
                    var handler = handlerFactory.GetHandler(queueMessage.TypeCode);

                    var result = await handler.ProcessAsync(queueMessage.TaskId);

                    if (result.IsSuccess)
                        logger.LogInformation("Задача {TaskId} успешно обработана", queueMessage.TaskId);
                    else
                        logger.LogWarning("Задача {TaskId} завершена с ошибкой. Статус: {Status}", queueMessage.TaskId, result.ErrorMessage);
                }
            });

            if (!isConnected)
                throw new Exception("Ошибка при подключении к RabbitMq");
        }

        public async Task StopProcessingAsync()
        {
            await rabbitService.DisposeAsync();
        }

    }
}
