import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { UpdateCurrentBreadcrumbName, UpdateBreadcrumbQueryParams } from '../../../../core/store/actions/breadcrumb.actions';
import { Store, Select } from '@ngxs/store';
import { fadeInAnimation } from '../../../../shared/animations/fade-in.animation';
import { staggerAnimation } from './stagger.animation';
import { take, filter, tap, switchMap, takeUntil, map, distinctUntilChanged } from 'rxjs/operators';
import { ProcessSelectors } from '../../../../core/store/selectors/process.selectors';
import { Process } from '../../../../core/models/process.model';
import { CustomerOrdersVisited, UpdateCurrentRouteQueryParams } from '../../../../core/store/actions/process.actions';
import { isBoolean } from '../../../../core/utils/app.utils';
import { Location } from '@angular/common';
import { ActivatedRoute, Router } from '@angular/router';
import { SharedSelectors } from 'apps/sales/src/app/core/store/selectors/shared.selectors';
import { User } from 'apps/sales/src/app/core/models/user.model';
import { isNullOrUndefined } from 'util';

@Component({
  selector: 'app-customer-edit',
  templateUrl: './customer-edit.component.html',
  styleUrls: ['./customer-edit.component.scss'],
  animations: [fadeInAnimation, staggerAnimation],
})
export class CustomerEditComponent implements OnInit, OnDestroy {
  @Select(ProcessSelectors.getCurrentProcess) currentProcess$: Observable<Process>;
  @Select(SharedSelectors.getCurrentProcessDetailsCustomer) customer$: Observable<User>;
  titles = {
    edit: 'Kundendetails',
    customerCard: 'Kundenkarte',
    orders: 'Bestellungen',
  };
  navigation = [];
  active = 'edit';
  destroy$ = new Subject();
  hasCustomerCard = false;
  customerId: number;

  constructor(private store: Store, private location: Location, private route: ActivatedRoute, private router: Router) {}

  ngOnInit() {
    this.route.queryParams
      .pipe(
        takeUntil(this.destroy$),
        tap((params) => {
          if (params['card']) {
            this.changeCards(params['card']);
            this.active = params['card'];
          } else {
            this.changeCards('edit');
            this.active = 'edit';
          }
        })
      )
      .subscribe();

    this.currentProcess$
      .pipe(
        filter((process: Process) => isBoolean(process, 'ordersOpenend')),
        take(1)
      )
      .subscribe((process: Process) => {
        if (process && process.ordersOpenend && process.currentRoute && process.currentRoute.includes('/customer/edit/')) {
          this.switch('orders');
        }
      });

    this.customer$
      .pipe(
        filter((data) => !isNullOrUndefined(data)),
        distinctUntilChanged(),
        takeUntil(this.destroy$),
        map((customer) => {
          if (customer && customer.features) {
            this.customerId = customer.id;
            return customer.features.findIndex((feature) => feature.key === 'p4mUser') !== -1;
          }
          return false;
        })
      )
      .subscribe((hasCustomerCard) => {
        if (!hasCustomerCard) {
          this.navigation = this.active === 'edit' ? ['orders'] : ['edit'];
        } else {
          this.navigation = this.active === 'edit' ? ['customerCard', 'orders'] : ['customerCard', 'edit'];
        }
        this.hasCustomerCard = hasCustomerCard;
      });
  }

  switch(newItem: string) {
    const index = this.navigation.indexOf(newItem);
    this.navigation[index] = this.active;
    this.active = newItem;
    this.store.dispatch(new CustomerOrdersVisited(newItem === 'orders' ? true : false));
    this.store.dispatch(new UpdateCurrentBreadcrumbName(this.titles[this.active], 'customer', { card: newItem }));
    this.store.dispatch(new UpdateCurrentRouteQueryParams({ card: newItem }));
    this.router.navigate([`/customer/edit/${this.customerId}`], { queryParams: { card: newItem } });
  }

  changeCards(newItem: string) {
    const index = this.navigation.indexOf(newItem);
    this.navigation[index] = this.active;
    this.active = newItem;
  }

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