using System.Reflection;
using HoneyBox.Admin.Business.Models.Config;
using HoneyBox.Admin.Business.Services.Interfaces;
using HoneyBox.Admin.Business.Services.Storage;
using Microsoft.Extensions.DependencyInjection;

namespace HoneyBox.Admin.Business.Extensions;

/// <summary>
/// 业务模块服务注册扩展方法
/// </summary>
public static class ServiceCollectionExtensions
{
    /// <summary>
    /// 添加 HoneyBox Admin 业务模块服务
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="mvcBuilder">MVC 构建器</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddAdminBusiness(this IServiceCollection services, IMvcBuilder mvcBuilder)
    {
        // 加载业务模块控制器
        var businessAssembly = typeof(ServiceCollectionExtensions).Assembly;
        mvcBuilder.AddApplicationPart(businessAssembly);

        // 自动注册业务服务
        RegisterBusinessServices(services, businessAssembly);

        // 注册存储提供者
        RegisterStorageProviders(services);

        return services;
    }

    /// <summary>
    /// 注册存储提供者
    /// </summary>
    private static void RegisterStorageProviders(IServiceCollection services)
    {
        // 注册本地存储提供者
        services.AddScoped<IStorageProvider, LocalStorageProvider>();

        // 注册腾讯云COS存储提供者
        services.AddScoped<IStorageProvider>(sp =>
        {
            var logger = sp.GetRequiredService<Microsoft.Extensions.Logging.ILogger<TencentCosProvider>>();
            var configService = sp.GetRequiredService<IAdminConfigService>();

            // 创建获取配置的委托
            Func<UploadSetting?> getUploadSetting = () =>
            {
                return configService.GetConfigAsync<UploadSetting>(ConfigKeys.Uploads).GetAwaiter().GetResult();
            };

            return new TencentCosProvider(logger, getUploadSetting);
        });
    }

    /// <summary>
    /// 自动注册业务服务
    /// 扫描程序集中所有实现了 I*Service 接口的服务类并注册
    /// </summary>
    private static void RegisterBusinessServices(IServiceCollection services, Assembly assembly)
    {
        var serviceTypes = assembly.GetTypes()
            .Where(t => t.IsClass && !t.IsAbstract && t.Name.EndsWith("Service"))
            .ToList();

        foreach (var serviceType in serviceTypes)
        {
            // 查找对应的接口 (例如 ConfigService -> IConfigService)
            var interfaceType = serviceType.GetInterfaces()
                .FirstOrDefault(i => i.Name == $"I{serviceType.Name}");

            if (interfaceType != null)
            {
                services.AddScoped(interfaceType, serviceType);
            }
        }
    }
}
