import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, Subject } from 'rxjs';
import { Process } from '../../core/models/process.model';
import { Store, Select } from '@ngxs/store';
import {
  AddProcess,
  ChangeCurrentRoute,
  ResetProcessProductFilters,
  SetOnlineCustomerCreationStatus,
} from '../../core/store/actions/process.actions';
import { Breadcrumb } from '../../core/models/breadcrumb.model';
import { ResetBreadcrumbsTo, AddBreadcrumb } from '../../core/store/actions/breadcrumb.actions';
import { takeUntil, distinctUntilChanged } from 'rxjs/operators';
import { ProcessSelectors } from '../../core/store/selectors/process.selectors';
import { ResetFilters } from '../../core/store/actions/filter.actions';
import { ModuleSwitcher } from '../../core/models/app-switcher.enum';
import { ModuleSwitcherService } from '../../core/services/module-switcher.service';
import { SetBranchProcessCurrentPath } from '../../core/store/actions/branch-process.actions';
import { InitRemissionState, SetRemissionFinishedProcessStatus, ResetRemissionState } from '../../core/store/actions/remission.actions';
import { RemissionSelectors } from '../../core/store/selectors/remission.selectors';
import { RemissionFinishingProcessStatus } from '../../modules/remission/models/remission-finishing-process-status.enum';
import { DeleteFormState } from '../../core/store/actions/forms.actions';
import { USER_FORM_STATE_KEY, USER_EXTRAS_FORM_STATE_KEY, USER_ERRORS_FORM_STATE_KEY } from '../../core/utils/app.constants';
import { CustomerHelperService } from '../../modules/customer/services/customer-helper.service';

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrls: ['./menu.component.scss'],
})
export class MenuComponent implements OnInit, OnDestroy {
  @Select(ProcessSelectors.getProcesses) processes$: Observable<Process[]>;
  module: ModuleSwitcher = ModuleSwitcher.Customer;
  processes: Process[] = [];
  destroy$ = new Subject();
  breadCrumbId = 'product';

  constructor(
    public router: Router,
    private store: Store,
    private moduleSwitcherService: ModuleSwitcherService,
    private customerHelperService: CustomerHelperService
  ) {}
  activeMenu = '';

  routeToMenu(menuPath: string, menuTag: string): void {
    if (this.processes && this.processes.length < 1 && this.module === ModuleSwitcher.Customer) {
      this.createProcess(menuPath);
    }
    this.activeMenu = menuTag;
    this.store.dispatch(
      new ResetBreadcrumbsTo(
        <Breadcrumb>{
          name: this.nameFromPath(menuPath),
          path: menuPath,
        },
        this.breadCrumbId,
        true
      )
    );
    if (menuTag === 'productsearch') {
      this.store.dispatch(new ResetFilters());
      this.store.dispatch(new ResetProcessProductFilters());
    }
    if (menuTag === 'remission') {
      this.store.dispatch(new InitRemissionState());
    }
    if (menuTag === 'customersearch') {
      this.store.dispatch(new DeleteFormState(USER_FORM_STATE_KEY));
      this.store.dispatch(new DeleteFormState(USER_EXTRAS_FORM_STATE_KEY));
      this.store.dispatch(new DeleteFormState(USER_ERRORS_FORM_STATE_KEY));
      this.store.dispatch(new SetOnlineCustomerCreationStatus({ error: false, invalidProperties: null }));
      this.customerHelperService.resetCustomerSearchView();
    }
    if (this.router.url === '/remission/finish' && menuTag === 'remission') {
      const processStatus = this.store.selectSnapshot(RemissionSelectors.getRemissionFinishingProcessStatus);
      if (processStatus === RemissionFinishingProcessStatus.start) {
        this.store.dispatch(new SetRemissionFinishedProcessStatus(RemissionFinishingProcessStatus.notSet));
      } else {
        this.store.dispatch(new SetRemissionFinishedProcessStatus(RemissionFinishingProcessStatus.notSet));
        this.navigateToNewRemissionList();
        return;
      }
    }

    if (this.module === ModuleSwitcher.Branch) {
      this.store.dispatch(new SetBranchProcessCurrentPath(menuPath));
    } else {
      this.store.dispatch(new ChangeCurrentRoute(menuPath));
    }
    this.router.navigate([menuPath]);
  }

  routeToMenuBranch(menuPath: string, menuTag: string): void {
    this.activeMenu = menuTag;
    this.router.navigate([menuPath]);
  }

  createProcess(menuPath: string) {
    const newProcess = <Process>{
      id: 1,
      name: 'Vorgang 1',
      currentRoute: menuPath,
    };
    this.store.dispatch(new AddProcess(newProcess));
  }

  routeFromPath(path: string) {
    if (path) {
      return path.substring(1, path.length);
    }
  }

  nameFromPath(path: string) {
    switch (path) {
      case '/product/search':
        this.breadCrumbId = 'product';
        return 'Artikelsuche';
      case '/customer/search':
        this.breadCrumbId = 'customer';
        return 'Kundensuche';
      case '/shelf/search':
        this.breadCrumbId = 'shelf';
        return 'Warenausgabe';
      case '/branch/main':
        this.breadCrumbId = 'goodsin';
        return 'Abholfach';
      case '/remission/create':
        this.breadCrumbId = 'remission';
        return 'Remission';
      case '/task-calendar/calendar':
        this.breadCrumbId = 'taskCalendar';
        return 'Tätigkeitskalendar';
      default:
        this.breadCrumbId = 'product';
        return 'Artikelsuche';
    }
  }

  ngOnInit() {
    this.processes$.pipe(takeUntil(this.destroy$)).subscribe((data: Process[]) => (this.processes = data));
    this.moduleSwitcherService.moduleSwitcher$
      .pipe(
        takeUntil(this.destroy$),
        distinctUntilChanged((prev, curr) => (prev && curr ? prev === curr : false))
      )
      .subscribe((activeModule: ModuleSwitcher) => {
        this.module = activeModule;
      });
  }

  ngOnDestroy() {
    this.destroy$.next();
  }

  private navigateToNewRemissionList() {
    this.store.dispatch(new ResetRemissionState());
    const path = '/remission/create';
    this.store.dispatch(
      new ResetBreadcrumbsTo(
        <Breadcrumb>{
          name: 'Remission',
          path: path,
        },
        'remission',
        true
      )
    );
    this.store.dispatch(new SetBranchProcessCurrentPath(path));
    this.router.navigate([path]);
  }
}
