namespace MyOffice.Web;

public partial class Program
{
	private static void MapRoutes(WebApplication app)
	{
		MapRoute(app, Routes.GlobalCurrencies, "General", "GetGlobalCurrencies", HttpMethod.Get);

		// Settings Currency
		MapRoute(app, Routes.SettingsCurrencies, "SettingCurrency", "Get", HttpMethod.Get);
		MapRoute(app, Routes.SettingsCurrencies, "SettingCurrency", "Add", HttpMethod.Post);
		MapRoute(app, Routes.SettingsCurrency, "SettingCurrency", "Update", HttpMethod.Put);
		MapRoute(app, Routes.SettingsCurrency, "SettingCurrency", "Delete", HttpMethod.Delete);
		MapRoute(app, Routes.SettingsCurrencyRate, "SettingCurrency", "AddRate", HttpMethod.Post);

		// Settings Account Categories
		MapRoute(app, Routes.SettingsAccountCategories, "SettingsAccountCategory", "AccountCategories", HttpMethod.Get);
		MapRoute(app, Routes.SettingsAccountCategory, "SettingsAccountCategory", "AccountCategory", HttpMethod.Get);
		MapRoute(app, Routes.SettingsAccountCategories, "SettingsAccountCategory", "AccountCategoriesAdd", HttpMethod.Post);
		MapRoute(app, Routes.SettingsAccountCategory, "SettingsAccountCategory", "AccountCategoriesUpdate", HttpMethod.Put);
		MapRoute(app, Routes.SettingsAccountCategory, "SettingsAccountCategory", "AccountCategoriesDelete", HttpMethod.Delete);

		// Settings Account
		MapRoute(app, Routes.SettingsAccounts, "SettingsAccount", "AccountsGet", HttpMethod.Get);
		MapRoute(app, Routes.SettingsAccounts, "SettingsAccount", "AccountsAdd", HttpMethod.Post);
		MapRoute(app, Routes.SettingsAccount, "SettingsAccount", "AccountsUpdate", HttpMethod.Put);
		MapRoute(app, Routes.SettingsAccount, "SettingsAccount", "AccountsDelete", HttpMethod.Delete);
		MapRoute(app, Routes.SettingsAccountAccountCategory, "SettingsAccount", "AccountsCategoryDelete", HttpMethod.Delete);
		MapRoute(app, Routes.SettingsAccountAccesses, "SettingsAccount", "AccountsAccessAdd", HttpMethod.Post);
		MapRoute(app, Routes.SettingsAccountAccess, "SettingsAccount", "AccountsAccessDelete", HttpMethod.Delete);
		MapRoute(app, Routes.SettingsAccountInvites, "SettingsAccount", "AccountInvites", HttpMethod.Get);
		MapRoute(app, Routes.SettingsAccountInviteAccept, "SettingsAccount", "AccountInviteAccept", HttpMethod.Post);
		MapRoute(app, Routes.SettingsAccountInviteReject, "SettingsAccount", "AccountInviteReject", HttpMethod.Post);

		// Settings Items
		MapRoute(app, Routes.SettingsItemCategories, "SettingsItem", "ItemsCategories", HttpMethod.Get);
		MapRoute(app, Routes.SettingsItemCategories, "SettingsItem", "ItemCategoriesAdd", HttpMethod.Post);
		MapRoute(app, Routes.SettingsItemCategory, "SettingsItem", "ItemCategoriesUpdate", HttpMethod.Put);
		MapRoute(app, Routes.SettingsItemCategory, "SettingsItem", "ItemCategoriesDelete", HttpMethod.Delete);
		MapRoute(app, Routes.SettingsItems, "SettingsItem", "Items", HttpMethod.Get);
		MapRoute(app, Routes.SettingsItem, "SettingsItem", "ItemsUpdate", HttpMethod.Put);
		MapRoute(app, Routes.SettingsItems, "SettingsItem", "ItemsPost", HttpMethod.Post);

		// Account
		MapRoute(app, Routes.Accounts, "Account", "AccountsGet", HttpMethod.Get);
		MapRoute(app, Routes.Account, "Account", "AccountGet", HttpMethod.Get);
		MapRoute(app, Routes.AccountMotions, "Account", "MotionsGet", HttpMethod.Get);
		MapRoute(app, Routes.AccountMotions, "Account", "MotionsPost", HttpMethod.Post);
		MapRoute(app, Routes.AccountMotion, "Account", "MotionsPut", HttpMethod.Put);
		MapRoute(app, Routes.AccountMotion, "Account", "MotionsDelete", HttpMethod.Delete);
		MapRoute(app, Routes.Items, "Account", "FindItems", HttpMethod.Get);

		// Dashboard
		MapRoute(app, Routes.Dashboard, "Dashboard", "Index", HttpMethod.Get);
		MapRoute(app, Routes.DashboardIncome, "Dashboard", "Income", HttpMethod.Get);
		MapRoute(app, Routes.DashboardOutcome, "Dashboard", "Outcome", HttpMethod.Get);

		// User
		MapRoute(app, Routes.UserRegister, "User", "Register", HttpMethod.Post);
		MapRoute(app, Routes.UserProfile, "User", "ProfileGet", HttpMethod.Get);
		MapRoute(app, Routes.UserProfile, "User", "ProfileUpdate", HttpMethod.Post);
		MapRoute(app, Routes.UserAttach, "User", "AttachProvider", HttpMethod.Post);
		MapRoute(app, Routes.UserDeattach, "User", "DeattachProvider", HttpMethod.Post);
	}

	private static void MapRoute(
		WebApplication app,
		string route,
		string controller,
		string action,
		params HttpMethod[] methods
	)
	{
		object? constraints = null;
		if (methods?.Any() == true)
		{
			constraints = new
			{
				httpMethod = new Microsoft.AspNetCore.Routing.Constraints.HttpMethodRouteConstraint(methods.Select(x => x.ToString()).ToArray())
			};
		}

		app.MapControllerRoute(
			name: $"{controller}_{action}",
			pattern: route,
			defaults: new
			{
				controller,
				action,
			},
			constraints: constraints
		);
	}
}

public static class Routes
{
	public static readonly string GlobalCurrencies = "api/general/currencies";
	public static readonly string SettingsCurrencies = "api/settings/currencies";
	public static readonly string SettingsCurrency = "api/settings/currencies/{id}";
	public static readonly string SettingsCurrencyRate = "api/settings/currencies/{id}/rate";

	public static readonly string SettingsAccountCategories = "api/settings/account-categories";
	public static readonly string SettingsAccountCategory = "api/settings/account-categories/{id}";

	public static readonly string SettingsAccounts = "api/settings/accounts";
	public static readonly string SettingsAccount = "api/settings/accounts/{id}";
	public static readonly string SettingsAccountAccountCategory = "api/settings/accounts/{id}/category/{categoryId}";

	public static readonly string SettingsAccountAccesses = "api/settings/accounts/{id}/access";
	public static readonly string SettingsAccountAccess = "api/settings/accounts/{id}/access/{userId}";
	public static readonly string SettingsAccountInvites = "api/settings/accounts/invites";
	public static readonly string SettingsAccountInviteAccept = "api/settings/accounts/invites/{id}/accept";
	public static readonly string SettingsAccountInviteReject = "api/settings/accounts/invites/{id}/reject";

	public static readonly string SettingsItemCategories = "api/settings/item-categories";
	public static readonly string SettingsItemCategory = "api/settings/item-categories/{id}";
	public static readonly string SettingsItems = "api/settings/items";
	public static readonly string SettingsItem = "api/settings/items/{id}";
	
	public static readonly string Accounts = "api/accounts";
	public static readonly string Account = "api/accounts/{id}";
	public static readonly string AccountMotions = "api/accounts/{id}/motions";
	public static readonly string AccountMotion = "api/accounts/{id}/motions/{motionId}";
	public static readonly string Items = "api/items";
	
	public static readonly string Dashboard = "api/dashboard";
	public static readonly string DashboardIncome = "api/dashboard/income";
	public static readonly string DashboardOutcome = "api/dashboard/outcome";
	
	public static readonly string UserRegister = "api/user/register";
	public static readonly string UserProfile = "api/user/profile";
	public static readonly string UserAttach = "api/user/attach";
	public static readonly string UserDeattach = "api/user/deattach";
}