using FluentValidation;
using FluentValidation.AspNetCore;
using Hotline.Api.Realtimes;
using Hotline.Application;
using Hotline.Application.Contracts;
using Hotline.CallCenter.Devices;
using Hotline.NewRock;
using Hotline.Permissions;
using Hotline.Repository.SqlSugar.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Serilog;
using Mapster;
using Tr.Sdk;
using XF.Domain.Dependency;
using XF.Domain.Filters;
using XF.Domain.Options;
using XF.EasyCaching;
using XF.Utility.MQ;
using Hotline.Ai.Jths;
using Hotline.Api.Sdk;
using Hotline.YbEnterprise.Sdk;

namespace Hotline.Api;

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://*:50100");
#endif
        
        //services.Configure<DeviceConfigs>(d => configuration.GetSection(nameof(DeviceConfigs)).Bind(d));
        services.Configure<IdentityConfiguration>(d => configuration.GetSection(nameof(IdentityConfiguration)).Bind(d));
        services.Configure<CallCenterConfiguration>(d => configuration.GetSection(nameof(CallCenterConfiguration)).Bind(d));
        services.Configure<AiVisitConfig>(d => configuration.GetSection("AiVisit").Bind(d));
        
        // Add services to the container.
        services
            .BatchInjectServices()
            .RegisterRepository()
            .AddApplication()
            //.AddClientCore(configuration)
            //.AddScoped<IPasswordHasher<Account>, PasswordHasher<Account>>()
            .AddScoped(typeof(IPasswordHasher<>), typeof(PasswordHasher<>))
            ;

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

        //Authentication
        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();

        //signalR
        services.RegisterSignalR(configuration);

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

        //mapster
        services.RegisterMapper();

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

        var callCenterConfiguration = configuration.GetSection("CallCenterConfiguration").Get<CallCenterConfiguration>();
        //迅时IPPBX
        services.AddNewRock(callCenterConfiguration.DeviceConfigs.Address);
  
        ////wex
        //services.AddWex(callCenterConfiguration.Wex.Address);
  
        //tr
        var trConfig = configuration.GetRequiredSection("Tr").Get<TrConfiguration>();
        services.AddTrSdk(trConfig.Address, trConfig.Username, trConfig.Password);
  
		//jths 
		services.AddAiJths(configuration.GetSection("AiQuality").Get<AiQualityConfig>().Url);
  
        //宜宾企业服务
        services.Configure<EnterpriseConfig>(d => configuration.GetSection("Enterprise").Bind(d));
        var enterpriseConfig = configuration.GetSection("Enterprise").Get<EnterpriseConfig>();
        services.AddYbEnterpriseSdk(enterpriseConfig?.AddressUrl);
  
        var aiVisitConfig = configuration.GetSection("AiVisit").Get<AiVisitConfig>();
        services.AddAiVisitService(
            aiVisitConfig.Url, 
            aiVisitConfig.Appkey, 
            aiVisitConfig.ServiceVersion);

        //sqlsugar
        services.AddSqlSugar(configuration);
        //services.AddWexDb(configuration);
        
        //validator
        services.AddFluentValidationAutoValidation(config =>
        {
            config.DisableDataAnnotationsValidation = true;
        })
            .AddValidatorsFromAssembly(typeof(AppContractsStartupExtensions).Assembly);

        //mq
        services.AddMq(configuration);

        //job
        services.RegisterJob();

        services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
        services.AddSingleton<IAuthorizationHandler, PermissionHandler>();

        //services.AddScoped<LogFilterAttribute>();
        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(c =>
            {
                //c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            });
        }
       
        app.UseCors(CorsOrigins);

        app.UseAuthentication();
        app.UseAuthorization();
        //app.MapHub<CallCenterHub>("/hubs/callcenter");
        app.MapHub<HotlineHub>("/hubs/hotline");

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

        return app;
    }
}