import { Injectable, Injector, ProviderToken } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
import { firstValueFrom, forkJoin } from 'rxjs';
import { take } from 'rxjs/operators';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { ArchivedDossiersService } from '@services/dossiers/archived-dossiers.service';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { ARCHIVE_ROUTE, DOSSIER_TEMPLATE_ID } from '@red/domain';
import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service';
import { TenantsService } from '@iqser/common-ui';

@Injectable({ providedIn: 'root' })
export class DossiersGuard implements CanActivate {
    constructor(
        private readonly _injector: Injector,
        private readonly _router: Router,
        private readonly _tenantsService: TenantsService,
        private readonly _dashboardStatsService: DashboardStatsService,
        private readonly _activeDossiersService: ActiveDossiersService,
        private readonly _archivedDossiersService: ArchivedDossiersService,
    ) {}

    async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
        const token: ProviderToken<DossiersService> = route.data.dossiersService;
        if (!token) {
            const services = [this._archivedDossiersService, this._activeDossiersService];
            const loading$ = forkJoin(services.map(service => service.loadAll().pipe(take(1))));
            await firstValueFrom(loading$);
            return true;
        }

        const dossiersService: DossiersService = this._injector.get<DossiersService>(token);
        const isArchive = dossiersService.routerPath === ARCHIVE_ROUTE;
        const dossierTemplateId = route.paramMap.get(DOSSIER_TEMPLATE_ID);
        const dossierTemplateStats = this._dashboardStatsService.find(dossierTemplateId);

        if (isArchive && dossierTemplateStats?.numberOfArchivedDossiers === 0) {
            await this._router.navigate([this._tenantsService.activeTenantId, 'main', dossierTemplateId, 'dossiers']);
            return false;
        }

        await firstValueFrom(dossiersService.loadAll());
        return true;
    }
}
