import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { ApplicationProcess, ApplicationService } from '@core/application';
import { BreadcrumbService } from '@core/breadcrumb';
import { first } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class CanActivateProductWithProcessIdGuard {
  constructor(
    private readonly _applicationService: ApplicationService,
    private readonly _breadcrumbService: BreadcrumbService,
  ) {}

  async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const processId = +route.params.processId;
    const process = await this._applicationService
      .getProcessById$(processId)
      .pipe(first())
      .toPromise();

    // if (!(process?.type === 'cart')) {
    //   // TODO:
    //   // Anderer Prozesstyp mit gleicher Id - Was soll gemacht werden?
    //   return false;
    // }

    if (!process) {
      await this._applicationService.createCustomerProcess(processId);
    }

    await this.removeBreadcrumbWithSameProcessId(route);
    this._applicationService.activateProcess(+route.params.processId);
    return true;
  }

  // Fix #3292: Alle Breadcrumbs die nichts mit dem aktuellen Prozess zu tun haben, müssen removed werden
  async removeBreadcrumbWithSameProcessId(route: ActivatedRouteSnapshot) {
    const crumbs = await this._breadcrumbService
      .getBreadcrumbByKey$(+route.params.processId)
      .pipe(first())
      .toPromise();

    // Entferne alle Crumbs die nichts mit der Artikelsuche zu tun haben
    if (crumbs.length > 1) {
      const crumbsToRemove = crumbs.filter(
        (crumb) => crumb.tags.find((tag) => tag === 'catalog') === undefined,
      );
      for (const crumb of crumbsToRemove) {
        await this._breadcrumbService.removeBreadcrumb(crumb.id);
      }
    }
  }

  processNumber(processes: ApplicationProcess[]) {
    const processNumbers = processes?.map((process) =>
      Number(process?.name?.replace(/\D/g, '')),
    );
    return !!processNumbers && processNumbers.length > 0
      ? this.findMissingNumber(processNumbers)
      : 1;
  }

  findMissingNumber(processNumbers: number[]) {
    // Ticket #3272 Bei Klick auf "+" bzw. neuen Prozess hinzufügen soll der neue Tab immer die höchste Nummer haben (wie aktuell im Produktiv)
    // ----------------------------------------------------------------------------------------------------------------------------------------

    // for (let missingNumber = 1; missingNumber < Math.max(...processNumbers); missingNumber++) {
    //   if (!processNumbers.find((number) => number === missingNumber)) {
    //     return missingNumber;
    //   }
    // }
    return Math.max(...processNumbers) + 1;
  }
}
