using MassTransit;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TakeoutSaaS.Infrastructure.Identity.Persistence;
using TakeoutSaaS.Infrastructure.Logs.Consumers;
using TakeoutSaaS.Module.Messaging.Options;

namespace TakeoutSaaS.Infrastructure.Logs.Extensions;

/// <summary>
/// 操作日志 Outbox 注册扩展。
/// </summary>
public static class OperationLogOutboxServiceCollectionExtensions
{
    /// <summary>
    /// 注册操作日志 Outbox 与消费者。
    /// </summary>
    /// <param name="services">服务集合。</param>
    /// <param name="configuration">配置源。</param>
    /// <returns>服务集合。</returns>
    public static IServiceCollection AddOperationLogOutbox(this IServiceCollection services, IConfiguration configuration)
    {
        // 1. 读取 RabbitMQ 配置
        var options = configuration.GetSection("RabbitMQ").Get<RabbitMqOptions>();
        if (options == null)
        {
            throw new InvalidOperationException("缺少 RabbitMQ 配置。");
        }

        // 2. 注册 MassTransit 与 Outbox
        services.AddMassTransit(configurator =>
        {
            configurator.AddConsumer<IdentityUserOperationLogConsumer>();
            configurator.AddEntityFrameworkOutbox<IdentityDbContext>(outbox =>
            {
                outbox.UsePostgres();
                outbox.UseBusOutbox();
            });
            configurator.UsingRabbitMq((context, cfg) =>
            {
                var virtualHost = string.IsNullOrWhiteSpace(options.VirtualHost) ? "/" : options.VirtualHost.Trim();
                var virtualHostPath = virtualHost == "/" ? "/" : $"/{virtualHost.TrimStart('/')}";
                var hostUri = new Uri($"rabbitmq://{options.Host}:{options.Port}{virtualHostPath}");
                cfg.Host(hostUri, host =>
                {
                    host.Username(options.Username);
                    host.Password(options.Password);
                });
                cfg.PrefetchCount = options.PrefetchCount;
                cfg.ConfigureEndpoints(context);
            });
        });
        // 3. 返回服务集合
        return services;
    }
}
