using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using SHH.CameraSdk;

// 确保 namespace 与 Program.cs 的引用一致
namespace SHH.CameraService;

public static class ServiceCollectionExtensions
{
    // ========================================================================
    // 1. 核心聚合方法 (对应 Program.cs 中的调用)
    // ========================================================================

    #region AddCameraBusinessServices

    /// <summary>
    /// [聚合] 注册所有核心业务 (包含逻辑处理、SDK、Gateway、视频流)
    /// </summary>
    public static void AddCameraBusinessServices(this IServiceCollection services, ServiceConfig config, Serilog.ILogger logger)
    {
        // 1.1 注册基础业务逻辑
        services.AddBusinessServices(config);

        // 1.2 注册视频流相关 (因为需要 Logger，所以单独传)
        services.AddStreamTargets(config, logger);
    }

    #endregion

    #region AddBusinessServices

    /// <summary>
    /// 集中注册 SDK、Workers、Gateway 等纯业务服务
    /// </summary>
    private static void AddBusinessServices(this IServiceCollection services, ServiceConfig config)
    {
        // 基础单例
        services.AddSingleton(config);
        services.AddSingleton<ProcessingConfigManager>();

        // 图像处理集群
        services.AddSingleton(sp => new ImageScaleCluster(4, sp.GetRequiredService<ProcessingConfigManager>()));
        services.AddSingleton(sp => new ImageEnhanceCluster(4, sp.GetRequiredService<ProcessingConfigManager>()));
        services.AddHostedService<PipelineConfigurator>();

        // SDK 与核心引擎
        services.AddCameraSdk(config.NumericId);
        services.AddHostedService<CameraEngineWorker>();

        // 监控与网关
        services.AddHostedService<DeviceStatusHandler>();
        services.AddHostedService<ParentProcessSentinel>();
        services.AddHostedService<GatewayService>();

        // 指令分发系统
        services.AddSingleton<InterceptorPipeline>();
        services.AddSingleton<CommandDispatcher>();
        services.AddSingleton<ICommandHandler, DeviceConfigHandler>();
        services.AddSingleton<ICommandHandler, RemoveCameraHandler>();
    }

    #endregion

    #region AddStreamTargets

    /// <summary>
    /// 注册视频流目标 (StreamTargets & GrpcSender)
    /// </summary>
    private static void AddStreamTargets(this IServiceCollection services, ServiceConfig config, Serilog.ILogger logger)
    {
        var netTargets = new List<StreamTarget>();
        if (config.VideoEndpoints != null)
        {
            foreach (var cfgVideo in config.VideoEndpoints)
            {
                netTargets.Add(new StreamTarget(new PushTargetConfig
                {
                    Name = cfgVideo.Description,
                    Endpoint = cfgVideo.Uri,
                    QueueCapacity = 10,
                }));
            }
        }

        logger.Information("[Core] 📋 加载视频流目标: {Count} 个", netTargets.Count);
        if (netTargets.Count > 0)
        {
            foreach (var item in netTargets)
                logger.Debug("[Core] 🔍 视频流目标详情: {@Targets}", new { item.Config });
        }

        services.AddSingleton<IEnumerable<StreamTarget>>(netTargets);
        services.AddHostedService<ImageMonitorController>();

        //// 动态注册 Sender Worker
        //foreach (var target in netTargets)
        //{
        //    // 注意：这里需要使用 Microsoft.Extensions.Logging.ILogger 来适配构造函数
        //    services.AddHostedService(sp =>
        //        new GrpcSenderWorker(target));
        //}

        foreach (var target in netTargets)
        {
            // Modified: 显式声明局部变量，防止 Lambda 捕获循环变量导致的引用重复
            var currentTarget = target;

            logger.Information("[DI] 准备启动 Worker 实例: {Name} -> {Url}",
                currentTarget.Config.Name, currentTarget.Config.Endpoint);

            // 使用工厂模式注册，确保传入的是当前的 currentTarget
            services.AddSingleton<IHostedService>(sp => new GrpcSenderWorker(currentTarget));
        }
    }

    #endregion

    // ========================================================================
    // 2. Web 支持与管道 (Program.cs 调用的另外两个方法)
    // ========================================================================

    #region AddWebSupport

    /// <summary>
    /// 注册 Controller, Swagger, Cors
    /// </summary>
    public static void AddWebSupport(this IServiceCollection services, ServiceConfig config)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("AllowAll", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
        });

        // 注册 Controller 并添加过滤器
        services.AddControllers(options =>
        {
            options.Filters.Add<UserActionFilter>();
        })
        .AddApplicationPart(typeof(CamerasController).Assembly) // 确保能扫描到 Controller
        .AddApplicationPart(typeof(MonitorController).Assembly);

        services.AddEndpointsApiExplorer();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = $"SHH Gateway #{config.AppId}", Version = "v1" });
        });
    }

    #endregion

    #region ConfigurePipeline

    /// <summary>
    /// 配置 HTTP 中间件管道
    /// </summary>
    public static void ConfigurePipeline(this WebApplication app, ServiceConfig config)
    {
        // 开启 Swagger
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", $"SHH Gateway #{config.AppId}"));

        // 简单健康检查端点
        app.MapGet("/", () => $"SHH Gateway {config.AppId} is running.");

        app.UseCors("AllowAll");
        app.MapControllers();
    }

    #endregion
}