import { Injectable, NgModule, inject } from '@angular/core';
import { Routes, RouterModule, ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot } from '@angular/router';
import { PrimaryNavigationComponent } from "./primary-navigation/primary-navigation.component";
import { CreateOrgComponent } from "./create-org/create-org.component";
import { DatacenterDetailsComponent } from "./datacenter-details/datacenter-details.component";
import { ApplicationsComponent } from "./applications/applications.component";
import { VappsComponent } from "./compute/vapps.component";
import { VmsComponent } from "./compute/vms.component";
import { DatacenterOverviewComponent } from "./datacenter-overview/datacenter-overview.component";
import { RESOURCES_ROUTE } from "./framework/app/plugin-container/plugin-container.module";
import { ExtensionContainerGuard } from "./framework/common/extensibility/extension-container/extension-container-guard";
import { ResourcesComponent } from "./framework/extensions/vdcs/resources/resources.component";
import { HomeComponent } from "./home/home.component";
import { DatacenterCardsComponent } from "./datacenter-overview/datacenter-cards.component";
import { ExtensionComponentRegistry } from "./framework/common/extensibility/extension-component.registry";
import { ANGULAR_APP_PRIMARY_NAVIGATION } from "./framework/common/extensibility/angular-apps/angular-apps.extension-point";
import { filter, interval, map, skipUntil } from "rxjs";
import { PluginContainerComponent } from "./framework/app/plugin-container/plugin-container.component";

const hyperPluginGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
	const registry = inject(ExtensionComponentRegistry);

	return interval(500).pipe(
		map(() => {
			const hyperPlugins = registry.getRegisteredComponents(ANGULAR_APP_PRIMARY_NAVIGATION);

			if (!hyperPlugins || !hyperPlugins.length) {
				return false;
			}
			
			const notActivatedHyperPlugin = hyperPlugins.find((hp) => {
				return !hp.angularAppDetails.activated;
			});

			if (notActivatedHyperPlugin) {
				return false;
			}

			return true;
		}),
		filter(Boolean),
	);
};

const routes: Routes = [
	{
		path: "",
		redirectTo: "welcome",
		pathMatch: "full",
	},
	{
		path: "welcome",
		component: HomeComponent,
	},
	{
		path: "plugins",
		component: PluginContainerComponent,
		children: [],
		canActivate: [
			hyperPluginGuard
		]
	},
	{
		path: "cloud/organizations",
		component: CreateOrgComponent,
		children: [],
		canActivate: [
			hyperPluginGuard
		]
	},
	{
		path: "vdcs",
		component: DatacenterOverviewComponent,
		canActivate: [
			hyperPluginGuard
		],
		children: [
			{
				path: "",
				component: DatacenterCardsComponent,
			},
			{
				path: RESOURCES_ROUTE,
				children: [
					{
						path: ":resourceExtensionId",
						component: ResourcesComponent,
						canDeactivate: [ExtensionContainerGuard],
					},
				]
			},
			{
				path: ":vdcId",
				component: DatacenterDetailsComponent,
				children: [
					{
						path: "",
						redirectTo: "vapps",
						pathMatch: "full",
					},
					{
						path: "vapps",
						component: VappsComponent,
					},
					{
						path: "vms",
						component: VmsComponent,
					},
					{
						path: RESOURCES_ROUTE,
						children: [
							{
								path: ":resourceExtensionId",
								component: ResourcesComponent,
								canDeactivate: [ExtensionContainerGuard],
							},
						]
					},
				]
			}
		],
	},
	{
		path: "applications",
		component: ApplicationsComponent,
		canActivate: [
			hyperPluginGuard
		],
		children: [
			{ path: '', redirectTo: 'vapps', pathMatch: "full" },
			{
				path: "vapps",
				component: VappsComponent,
			},
			{
				path: "vms",
				component: VmsComponent,
			},
			{
				path: RESOURCES_ROUTE,
				children: [
					{
						path: ":resourceExtensionId",
						component: ResourcesComponent,
						canDeactivate: [ExtensionContainerGuard],
					},
				]
			}
		],
	}
];

@NgModule({
	imports: [RouterModule.forRoot(routes)],
	exports: [RouterModule]
})
export class AppRoutingModule { }
