import { Component, ChangeDetectionStrategy, ViewChildren, QueryList } from '@angular/core';
import { ApplicationProcess, ApplicationService } from '@core/application';
import { first, map, shareReplay, switchMap, tap } from 'rxjs/operators';
import { NotificationsHub } from '@hub/notifications';
import { ModalNotificationsComponent } from '@modal/notifications';
import { ConfirmModalData, UiConfirmModalComponent, UiModalService } from '@ui/modal';
import { Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { combineLatest } from 'rxjs';
import { AuthService } from '@core/auth';
import { DomainAvailabilityService } from '@domain/availability';
import { ShellProcessTabComponent } from '@shell/process';
import { Config } from '@core/config';

@Component({
  selector: 'app-shell',
  templateUrl: 'shell.component.html',
  styleUrls: ['shell.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShellComponent {
  @ViewChildren('processTabs')
  readonly processTabs: QueryList<ShellProcessTabComponent>;

  notifications$ = this._notificationsHub.notifications$;

  notificationCount$ = this.notifications$.pipe(map((message) => message?.data?.length));

  get activatedProcessId$() {
    return this._appService.getActivatedProcessId$().pipe(
      tap((activatedProcessId) => {
        this.processTabs?.find((process) => process?.process?.id === activatedProcessId && !process?.isActive)?.slideIntoView();
      })
    );
  }

  get section$() {
    return this._appService.getSection$().pipe(shareReplay());
  }

  get processes$() {
    return this.section$.pipe(switchMap((section) => this._appService.getProcesses$(section)));
  }

  get remissionProcess$() {
    return this._appService.getProcessById$(this._config.get('process.ids.remission'));
  }

  get remissionUrl$() {
    return this.remissionProcess$.pipe(
      map((process) => (process?.data?.active ? `/filiale/remission/${process.data.active}/list` : '/filiale/remission'))
    );
  }

  get remissionQueryParams$() {
    return this.remissionProcess$.pipe(
      map((process) => (process?.data?.active && process?.data?.queryParams ? process.data.queryParams : {}))
    );
  }

  get addProcessLabel$() {
    return combineLatest([this.section$, this.processes$]).pipe(
      map(([section, processes]) => (section === 'customer' && processes.length === 0 ? 'VORGANG STARTEN' : ''))
    );
  }

  get canAddProcess$() {
    return this.section$.pipe(map((section) => section === 'customer'));
  }

  get currentBranch$() {
    return this._availabilityService.getCurrentBranch();
  }

  constructor(
    private readonly _appService: ApplicationService,
    private readonly _config: Config,
    private readonly _notificationsHub: NotificationsHub,
    private readonly _modal: UiModalService,
    private readonly _router: Router,
    private readonly _breadcrumbService: BreadcrumbService,
    private readonly _authService: AuthService,
    private readonly _availabilityService: DomainAvailabilityService
  ) {}

  async setSection(section: 'customer' | 'branch') {
    this._appService.setSection(section);

    const lastProcessId = (await this._appService.getLastActivatedProcessWithSection$(section).pipe(first()).toPromise())?.id;
    if (lastProcessId) {
      this.activateProcess(lastProcessId);
    } else {
      this._router.navigate([section === 'customer' ? '/kunde' : '/filiale']);
    }
  }

  // Process werden über Guards erstellt und aktiviert. An dieser Stelle wird nur navigiert
  async addProcess() {
    const processId = Date.now();
    await this._router.navigate(['/kunde', processId, 'product']);
  }

  async activateProcess(activatedProcessId: number) {
    const latestCrumb = await this._breadcrumbService?.getLastActivatedBreadcrumbByKey$(activatedProcessId)?.pipe(first()).toPromise();
    if (latestCrumb) {
      await this._router.navigate([latestCrumb.path], { queryParams: latestCrumb.params });
    } else {
      await this._router.navigate(['/kunde']);
    }
  }

  async closeProcess(processId: number) {
    this._appService.removeProcess(processId);

    const processes = await this.processes$.pipe(first()).toPromise();
    if (processes.length === 0) {
      await this._router.navigate(['/kunde', 'dashboard']);
      return;
    }

    const section = await this.section$.pipe(first()).toPromise();
    const lastActivatedProcess = await this._appService.getLastActivatedProcessWithSection$(section).pipe(first()).toPromise();
    this.activateProcess(lastActivatedProcess?.id);
  }

  processAction(process: ApplicationProcess) {
    if (process?.type === 'cart') {
      this._router.navigate(['/kunde', process.id, 'cart']);
    }
  }

  async logout() {
    await this._authService.logout();
  }

  async openNotifications() {
    const notifications = await this.notifications$.pipe(first()).toPromise();
    this._modal.open({
      content: ModalNotificationsComponent,
      data: notifications,
      config: {
        showScrollbarY: false,
      },
    });
  }

  trackByIdFn(process: ApplicationProcess) {
    return process.id;
  }
}
