import { NgModule } from '@angular/core';
import { RouteReuseStrategy, RouterModule } from '@angular/router';
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
import { BaseScreenComponent } from '@components/base-screen/base-screen.component';
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
import { DashboardGuard } from '@guards/dashboard-guard.service';
import { DossierFilesGuard } from '@guards/dossier-files-guard';
import { templateExistsWhenEnteringDossierList } from '@guards/dossier-template-exists.guard';
import { DossierTemplatesGuard } from '@guards/dossier-templates.guard';
import { loadActiveDossiersGuard, loadAllDossiersGuard, loadArchivedDossiersGuard } from '@guards/dossiers.guard';
import { editAttributeGuard } from '@guards/edit-attribute.guard';
import { FeaturesGuard } from '@guards/features-guard.service';
import { ifLoggedIn } from '@guards/if-logged-in.guard';
import { ifNotLoggedIn } from '@guards/if-not-logged-in.guard';
import { TrashGuard } from '@guards/trash.guard';
import { CompositeRouteGuard, DEFAULT_REDIRECT_KEY, IqserPermissionsGuard, IqserRoutes, orderedAsyncGuards } from '@iqser/common-ui';
import { TenantSelectComponent } from '@iqser/common-ui/lib/tenants';
import { hasAnyRoleGuard, IqserAuthGuard } from '@iqser/common-ui/lib/users';
import { CustomRouteReuseStrategy } from '@iqser/common-ui/lib/utils';
import { ARCHIVE_ROUTE, BreadcrumbTypes, DOSSIER_ID, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE, FILE_ID } from '@red/domain';
import { RedRoleGuard } from '@users/red-role.guard';
import { Roles } from '@users/roles';
import { mainGuard } from '@utils/main.guard';
import { webViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
import { ACTIVE_DOSSIERS_SERVICE } from './tokens';

const dossierTemplateIdRoutes: IqserRoutes = [
    {
        path: `${DOSSIERS_ROUTE}`,
        canActivate: [loadActiveDossiersGuard(), IqserPermissionsGuard],
        data: {
            permissions: {
                allow: [Roles.files.readStatus],
                redirectTo: '/auth-error',
            },
        },
        children: [
            {
                path: `:${DOSSIER_ID}`,
                canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
                canDeactivate: [editAttributeGuard],
                data: {
                    routeGuards: [DossierFilesGuard],
                    breadcrumbs: [BreadcrumbTypes.dossierTemplate, BreadcrumbTypes.dossier],
                    dossiersService: ACTIVE_DOSSIERS_SERVICE,
                    permissions: {
                        allow: [Roles.dossierAttributes.read, Roles.dossierAttributes.readConfig],
                        redirectTo: '/auth-error',
                    },
                    skeleton: 'dossier',
                },
                loadChildren: () => import('./modules/dossier-overview/dossier-overview.module').then(m => m.DossierOverviewModule),
            },
            {
                path: `:${DOSSIER_ID}/file/:${FILE_ID}`,
                canActivate: [CompositeRouteGuard, IqserPermissionsGuard, webViewerLoadedGuard()],
                data: {
                    routeGuards: [DossierFilesGuard],
                    breadcrumbs: [BreadcrumbTypes.dossierTemplate, BreadcrumbTypes.dossier, BreadcrumbTypes.file],
                    dossiersService: ACTIVE_DOSSIERS_SERVICE,
                    permissions: {
                        allow: [Roles.readRedactionLog, Roles.files.downloadOriginal, Roles.highlights.read],
                        redirectTo: '/auth-error',
                    },
                },
                loadChildren: () => import('./modules/file-preview/file-preview.module').then(m => m.FilePreviewModule),
            },
            {
                path: '',
                pathMatch: 'full',
                loadChildren: () => import('./modules/dossiers-listing/dossiers-listing.module').then(m => m.DossiersListingModule),
                data: {
                    breadcrumbs: [BreadcrumbTypes.dossierTemplate],
                },
            },
        ],
    },
    {
        path: `${ARCHIVE_ROUTE}`,
        loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule),
        canActivate: [CompositeRouteGuard, webViewerLoadedGuard(), loadArchivedDossiersGuard()],
        data: {
            routeGuards: [FeaturesGuard],
            features: [DOSSIERS_ARCHIVE],
        },
    },
    {
        path: '**',
        redirectTo: `${DOSSIERS_ROUTE}`,
        pathMatch: 'full',
    },
];

const mainRoutes: IqserRoutes = [
    {
        path: '',
        redirectTo: 'dashboard',
        pathMatch: 'full',
    },
    {
        path: 'account',
        loadChildren: () => import('./modules/account/account.module').then(m => m.AccountModule),
    },
    {
        path: 'admin',
        loadChildren: () => import('./modules/admin/admin.module').then(m => m.AdminModule),
        canActivate: [RedRoleGuard],
    },
    {
        path: 'dashboard',
        loadChildren: () => import('./modules/dashboard/dashboard.module').then(m => m.DashboardModule),
        canActivate: [CompositeRouteGuard],
        data: {
            routeGuards: [IqserAuthGuard, RedRoleGuard, IqserPermissionsGuard, DossierTemplatesGuard, DashboardGuard],
            permissions: {
                allow: [
                    Roles.any,
                    Roles.templates.read,
                    Roles.fileAttributes.readConfig,
                    Roles.dictionaryTypes.read,
                    Roles.colors.read,
                    Roles.states.read,
                    Roles.notifications.read,
                    'RED_USER',
                ],
                redirectTo: {
                    RED_USER: '/main/admin',
                    [Roles.templates.read]: '/main/admin',
                    [DEFAULT_REDIRECT_KEY]: '/auth-error',
                },
            },
            skeleton: 'dashboard',
        },
    },
    {
        path: 'downloads',
        // TODO: transform into a lazy loaded module
        component: DownloadsListScreenComponent,
        canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
        data: {
            routeGuards: [IqserAuthGuard, RedRoleGuard],
            permissions: {
                allow: Roles.readDownloadStatus,
                redirectTo: '/auth-error',
            },
        },
    },
    {
        path: 'search',
        loadChildren: () => import('./modules/search/search.module').then(m => m.SearchModule),
        canActivate: [CompositeRouteGuard, IqserPermissionsGuard, loadAllDossiersGuard()],
        data: {
            routeGuards: [IqserAuthGuard, RedRoleGuard],
            permissions: {
                allow: [Roles.search],
                redirectTo: '/auth-error',
            },
        },
    },
    {
        path: 'trash',
        loadChildren: () => import('./modules/trash/trash.module').then(m => m.TrashModule),
        canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
        data: {
            routeGuards: [IqserAuthGuard, RedRoleGuard, TrashGuard],
            permissions: {
                allow: [Roles.dossiers.read, Roles.files.readStatus],
                redirectTo: '/auth-error',
            },
        },
    },
    {
        path: `:${DOSSIER_TEMPLATE_ID}`,
        children: dossierTemplateIdRoutes,
        canActivate: [CompositeRouteGuard, IqserPermissionsGuard, templateExistsWhenEnteringDossierList()],
        data: {
            routeGuards: [IqserAuthGuard, RedRoleGuard],
            permissions: {
                allow: [
                    Roles.any,
                    Roles.templates.read,
                    Roles.fileAttributes.readConfig,
                    Roles.dictionaryTypes.read,
                    Roles.colors.read,
                    Roles.states.read,
                    Roles.notifications.read,
                    Roles.dossiers.read,
                    'RED_USER',
                ],
                redirectTo: {
                    [Roles.any]: '/auth-error',
                    RED_USER: '/main/admin',
                    [DEFAULT_REDIRECT_KEY]: '/',
                },
            },
        },
    },
];

const routes: IqserRoutes = [
    {
        path: '',
        pathMatch: 'full',
        canActivate: [ifNotLoggedIn()],
        component: TenantSelectComponent,
    },
    {
        path: ':tenant',
        redirectTo: ':tenant/main',
        pathMatch: 'full',
    },
    {
        path: ':tenant/main',
        canActivate: [orderedAsyncGuards([ifLoggedIn(), mainGuard()])],
        component: BaseScreenComponent,
        children: mainRoutes,
    },
    {
        path: ':tenant/auth-error',
        component: AuthErrorComponent,
        canActivate: [hasAnyRoleGuard()],
    },
    {
        path: '**',
        redirectTo: 'main',
        pathMatch: 'full',
    },
];

@NgModule({
    imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled', bindToComponentInputs: true })],
    providers: [{ provide: RouteReuseStrategy, useExisting: CustomRouteReuseStrategy }],
    exports: [RouterModule],
})
export class AppRoutingModule {}
