using Blazor.AdminLte;
using Blazored.LocalStorage;
using Blazored.Modal;
using Blazored.Toast;
using DiplomovaPrace.Contracts.Addresses;
using DiplomovaPrace.Contracts.Orders;
using DiplomovaPrace.Contracts.ProductCategories;
using DiplomovaPrace.Contracts.Products;
using DiplomovaPrace.Contracts.Security;
using DiplomovaPrace.Web.Admin.Infrastructure;
using DiplomovaPrace.Web.Admin.Services;
using Fluxor;
using Grpc.Net.Client.Web;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using ProtoBuf.Grpc.ClientFactory;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Tewr.Blazor.FileReader;

namespace DiplomovaPrace.Web.Admin
{
	public class Program
	{
		public static async Task Main(string[] args)
		{
			var builder = WebAssemblyHostBuilder.CreateDefault(args);

			builder.Services.AddBlazoredLocalStorage();
			builder.Services.AddBlazoredToast();
			builder.Services.AddBlazoredModal();

			builder.Services.AddFileReaderService();

			//builder.Services.AddBootstrapCss();

			builder.RootComponents.Add<App>("#app");
			builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
			builder.Services.AddAdminLte();

			// Http client authorization header
			builder.Services.AddTransient<AuthorizationHeaderHandler>();
			builder.Services.AddHttpClient("ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
				.AddHttpMessageHandler<AuthorizationHeaderHandler>();
			builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ServerAPI"));

			//gRPC
			builder.Services.AddCodeFirstGrpcClient<IAddressFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IProductFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IProductCategoryFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IDeliveryTypeFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IOrderFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IOrderStateFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IPaymentStateFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<IPaymentTypeFacadeContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
			builder.Services.AddCodeFirstGrpcClient<ISecurityServiceContract>(o => o.Address = new Uri(builder.HostEnvironment.BaseAddress))
				.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()))
				.AddHttpMessageHandler<AuthorizationHeaderHandler>();

			// Authentization FE
			builder.Services.AddOptions();
			builder.Services.AddAuthorizationCore();
			builder.Services.AddScoped<JwtAuthenticationStateProvider>();
			builder.Services.AddScoped<AuthenticationStateProvider>(options => options.GetRequiredService<JwtAuthenticationStateProvider>());

			//Services
			builder.Services.AddTransient<IProductService, ProductService>();
			builder.Services.AddTransient<IProductCategoryService, ProductCategoryService>();
			builder.Services.AddTransient<ILoginService, LoginService>();
			builder.Services.AddTransient<ISecurityService, SecurityService>();
			builder.Services.AddTransient<IOrderService, OrderService>();

			builder.Services.AddFluxor(options => options
				.ScanAssemblies(typeof(Program).Assembly)
				.UseRouting());

			await builder.Build().RunAsync().ConfigureAwait(false);
		}
	}
}
