using Hcs.WebApp.BackgroundServices;
using Hcs.WebApp.BackgroundServices.CampaignManagers;
using Hcs.WebApp.BackgroundServices.OperationExecutors;
using Hcs.WebApp.BackgroundServices.ResultGetters;
using Hcs.WebApp.Components;
using Hcs.WebApp.Components.Shared;
using Hcs.WebApp.Data.Hcs;
using Hcs.WebApp.Data.Identity;
using Hcs.WebApp.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Radzen;
using Radzen.Blazor;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddControllers();
builder.Services.AddRadzenComponents();

builder.Services.AddHttpClient("WithIdentity").AddHeaderPropagation(x => x.Headers.Add("Cookie"));
builder.Services.AddHeaderPropagation(x => x.Headers.Add("Cookie"));
builder.Services.AddAuthentication();
builder.Services.AddAuthorization();

var identityConnection = builder.Configuration.GetConnectionString("IdentityConnection") ?? throw new InvalidOperationException("Не удалось получить значение из 'IdentityConnection'");
builder.Services.AddDbContextFactory<AppIdentityDbContext>(options => options.UseSqlServer(identityConnection));

builder.Services
    .AddIdentity<AppUser, AppRole>(options =>
    {
        options.Password.RequiredLength = 6;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireDigit = false;
        options.Password.RequireLowercase = false;
        options.Password.RequireUppercase = false;
        options.Password.RequiredUniqueChars = 1;
    })
    .AddEntityFrameworkStores<AppIdentityDbContext>()
    .AddDefaultTokenProviders();

string hcsConnection;
if (builder.Environment.IsDevelopment())
{
    hcsConnection = builder.Configuration.GetConnectionString("HcsSit2Connection") ?? throw new InvalidOperationException("Не удалось получить значение из 'HcsSit2Connection'");
}
else
{
    hcsConnection = builder.Configuration.GetConnectionString("HcsProdConnection") ?? throw new InvalidOperationException("Не удалось получить значение из 'HcsProdConnection'");
}
builder.Services.AddDbContextFactory<HcsDbContext>(options => options.UseSqlServer(hcsConnection, options =>
{
    options.EnableRetryOnFailure(
        maxRetryCount: 6,
        maxRetryDelay: TimeSpan.FromSeconds(30),
        errorNumbersToAdd: null);
}));

#if USE_MOCK
builder.Services.AddTransient<IClientProvider, MockClientProvider>();
#else
builder.Services.AddTransient<IClientProvider, ClientProvider>();
#endif
builder.Services.AddScoped<IdentityService>();
builder.Services.AddScoped<UsersService>();
builder.Services.AddScoped<HeadquartersService>();
builder.Services.AddScoped<RegistryService>();

builder.Services.AddSingleton<CampaignManagementState>();
builder.Services.AddSingleton<OperationExecutionState>();
builder.Services.AddSingleton<ResultWaitState>();
builder.Services.AddSingleton<ManagerFactory>();
builder.Services.AddSingleton<ExecutorFactory>();
builder.Services.AddSingleton<ResultGetterFactory>();

builder.Services.AddHostedService<CampaignManagementService>();
builder.Services.AddHostedService<OperationExecutionService>();
builder.Services.AddHostedService<ResultWaitService>();

var activator = new RadzenComponentActivator();
activator.Override(typeof(RadzenDataGrid<>), typeof(LocalizedRadzenDataGrid<>));
builder.Services.AddSingleton<IComponentActivator>(activator);

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/error", createScopeForErrors: true);
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseHeaderPropagation();
app.UseRouting();
app.UseAntiforgery();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app
    .MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();
