using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.Core.Common.Interfaces;
using PARR.Core.Common.Interfaces.RabbitServices;
using PARR.Domain.Common.Rabbit.Messages;

namespace PARR.TemplateActivator;

internal class MqTemplateActivator : IMqTemplateActivator
{
    private readonly MqSettings mqSettings;
    private readonly IRabbitService mqService;
    private readonly ILogger<MqTemplateActivator> logger;
    private readonly ITransformService transformService;
    private readonly IValidatorService validatorService;
    private readonly IServiceProvider serviceProvider;

    public MqTemplateActivator(
        MqSettings mqSettings,
        IRabbitService mqService,
        ILogger<MqTemplateActivator> logger,
        ITransformService transformService,
        IValidatorService validatorService,
        IServiceProvider serviceProvider
        )
    {
        this.mqSettings = mqSettings;
        this.mqService = mqService;
        this.logger = logger;
        this.transformService = transformService;
        this.validatorService = validatorService;
        this.serviceProvider = serviceProvider;
    }
    public async Task StartAsync()
    {
        var isConnected = await mqService.InitConsumerAsync(mqSettings, UpdateTemplateStatusAsync);

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

    private async Task UpdateTemplateStatusAsync(string msg)
    {
        logger.LogInformation($"Получили запрос: {msg}");

        var query = transformService.GetModelFromJson<TemplateActivatorMq>(msg);
        if (query == null)
            return;

        if (!await validatorService.IsValidObjectIdAsync(query.Id, query.EntityType))
        {
            logger.LogError($"Не найдет объект {nameof(query.Id)}: {query.Id}, типа {nameof(query.EntityType)}: {query.EntityType}.");
            return;
        }

        using (var scope = serviceProvider.CreateScope())
        {
            var service = scope.ServiceProvider.GetService<ITemplateActivator>();
            if (service == null)
                throw new Exception($"Не найден сервис: {nameof(service.GetType)}");

            await service.ChangeStateAsync(query);
        }
    }

    public async Task StopAsync()
    {
        await mqService.DisposeAsync();
    }
}
