using DataSharing.CityStateDataExchange;
using DataSharing.LuZhou;
using DataSharing.LuZhou.LuZhou110;
using DataSharing.LuZhou.LZCityPortal;
using DataSharing.Police110;
using DataSharing.Police110.DaoShu110;
using DataSharing.Police110.DCJT110;
using DataSharing.Police110.HaiNengDa110;
using DataSharing.Repository.Extensions;
using DataSharing.SendTask;
using DataSharing.YiBin.Enterprise;
using DataSharing.YiBin.ZzptPlatformsYB;
using DataSharing.ZiGong.TianQue;
using FluentValidation;
using FluentValidation.AspNetCore;
using Hotline.Application;
using Mapster;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Serilog;
using XF.Domain.Dependency;
using XF.Domain.Filters;
using XF.Domain.Options;
using XF.EasyCaching;
using XF.Utility.MQ;

namespace DataSharing.Host;

internal static class StartupExtensions
{
    const string CorsOrigins = "CorsOrigins";

    internal static WebApplication ConfigureServices(this WebApplicationBuilder builder)
    {
        var services = builder.Services;
        var configuration = builder.Configuration;

        services.AddHttpContextAccessor();

#if DEBUG
        builder.WebHost.UseUrls("http://*:50105");
#endif

        services.AddHttpClient();

        services.Configure<IdentityConfiguration>(d => configuration.GetSection(nameof(IdentityConfiguration)).Bind(d));
        services.Configure<ChannelConfiguration>(d => configuration.GetSection(nameof(ChannelConfiguration)).Bind(d));
        services.Configure<SharingConfiguration>(d => configuration.GetSection(nameof(SharingConfiguration)).Bind(d));

        //根据市州编码判断属于哪个市州，启用对应的推送服务
        var sharingConfig = configuration.GetSection("SharingConfiguration").Get<SharingConfiguration>();
        if (sharingConfig != null && sharingConfig.CityCode == ConfigurationConsts.YiBin)//宜宾
        {
            services.AddScoped<ISendTaskDataService, DataSharing.YiBin.YiBinSendTaskDataService>();
            services.AddScoped<IPoliceService, DaoShuService>();//110
            services.AddScoped<IEnterpriseService, EnterpriseService>();//企业专班
            services.AddScoped<IZzptService, ZzptService>();//综治平台
            services.AddScoped<ICityStateDataExchangeService, CityStateDataExchangeService>();//市州互转

            //应急管理局业务
            if (sharingConfig.CityYiBin.YingJiGuanLiJu != null && sharingConfig.CityYiBin.YingJiGuanLiJu.DbConnectionString != null)
            {
                services.AddYingJiDb(sharingConfig.CityYiBin.YingJiGuanLiJu);
            }
        }
        else if (sharingConfig != null && sharingConfig.CityCode == ConfigurationConsts.ZiGong)//自贡
        {
            services.AddScoped<ISendTaskDataService, DataSharing.ZiGong.ZiGongSendTaskDataService>();
            services.AddScoped<IPoliceService, DcjtService>();//110
            services.AddScoped<ICityStateDataExchangeService, CityStateDataExchangeService>();//市州互转
                                                                                              // services.AddScoped<ITianQueService, TianQueService>();//随手拍天阙
        }
        else if (sharingConfig != null && sharingConfig.CityCode == ConfigurationConsts.LuZhou)//泸州
        {
            services.AddScoped<ISendTaskDataService, DataSharing.LuZhou.LuZhouSendTaskDataService>();
            services.AddScoped<IPoliceService, HndService>();//110 
            services.AddScoped<ICityStateDataExchangeService, CityStateDataExchangeService>();//市州互转
            services.AddScoped<ILuZhou110Service, LuZhou110Service>();//泸州110
            services.AddScoped<ILZCityPortalSiteService, LZCityPortalSiteService>();//泸州市政府门户网站
        }

        services
            .BatchInjectServices()
            .RegisterRepository()
            .AddApplication()
            ;

        services.RegisterAuthentication(configuration);

        services.AddControllers(options =>
            {
                options.Filters.Add<UnifyResponseFilter>();
                options.Filters.Add<UserFriendlyExceptionFilter>();
            })
            ;

        // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
        services.AddEndpointsApiExplorer();

        //swagger
        services.RegisterSwagger();

        /* CORS */
        services.RegisterCors(configuration, CorsOrigins);

        //mapster
        services.RegisterMapper();

        //mediatr
        services.AddMediatR(d => { d.RegisterServicesFromAssembly(typeof(ApplicationStartupExtensions).Assembly); });

        //sqlsugar
        services.AddSqlSugar(configuration);

        //关闭TS时间
        AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
        AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);

        //cache
        services.AddCache(d =>
        {
            var cacheConfig = configuration.GetSection("Cache").Get<CacheOptions>();
            cacheConfig.Adapt(d);
            d.Prefix = "DataSharing";
            d.TopicName = "Dsharing-topic";
        });

        //validator
        services.AddFluentValidationAutoValidation(config => { config.DisableDataAnnotationsValidation = true; })
            .AddValidatorsFromAssembly(typeof(ApplicationStartupExtensions).Assembly);

        //mq
        //  services.AddMq(configuration);
        services.AddMq(() => configuration.GetSection(nameof(MqConfiguration)).Get<MqConfiguration>());

        services.Configure<KestrelServerOptions>(options =>
        {
            options.Limits.MaxRequestBodySize = int.MaxValue;
        });

        services.Configure<FormOptions>(options =>
        {
            options.ValueLengthLimit = int.MaxValue;
            options.MultipartBodyLengthLimit = int.MaxValue;
        });
        ////retry pipeline
        //services.AddResiliencePipeline(StrategyDefaults.RetryStrategy, d =>
        //{
        //    d.AddRetry(new RetryStrategyOptions
        //        {
        //            Delay = TimeSpan.FromSeconds(5),
        //        //BackoffType = DelayBackoffType.Constant,
        //        //// UseJitter = true,
        //        //MaxDelay = TimeSpan.FromSeconds(10),
        //        MaxRetryAttempts = 10
        //    });
        //        //.AddTimeout(TimeSpan.FromSeconds(5));
        //});

        ////根据市州编码判断属于哪个市州，启用对应的推送服务
        //var sharingConfig = configuration.GetSection("SharingConfiguration").Get<SharingConfiguration>();
        //if (sharingConfig.CityCode == ConfigurationConsts.YiBin)
        //{
        //    services.AddScoped<ISendTaskDataService, DataSharing.YiBin.YiBinSendTaskDataService>();
        //    services.AddScoped<IPolice110Service, DaoShuService>();
        //}
        //else if (sharingConfig.CityCode == ConfigurationConsts.ZiGong)
        //{
        //    services.AddScoped<ISendTaskDataService, DataSharing.ZiGong.ZiGongSendTaskDataService>();
        //    services.AddScoped<IPolice110Service, DcjtService>();
        //}


        //job
        services.RegisterJob(sharingConfig);
        //services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
        //services.AddSingleton<IAuthorizationHandler, PermissionHandler>();

        return builder.Build();
    }

    internal static WebApplication ConfigurePipelines(this WebApplication app)
    {
        app.UseSerilogRequestLogging();

        // Configure the HTTP request pipeline.
        var swaggerEnable = app.Configuration.GetSection("Swagger").Get<bool>();
        if (swaggerEnable)
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.UseCors(CorsOrigins);

        app.UseAuthentication();
        app.UseAuthorization();

        app.MapControllers()
            .RequireAuthorization();
        //app.MapSubscribeHandler();

        return app;
    }
}