import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CrmCustomerService } from '@domain/crm';
import { CustomerDTO } from '@swagger/crm';

import { first, map, shareReplay, switchMap, tap, withLatestFrom } from 'rxjs/operators';
import { OrderListItemDTO } from '@swagger/oms';
import { DomainOmsService } from '@domain/oms';
import { Observable } from 'rxjs/internal/Observable';
import { BehaviorSubject, combineLatest, Subscription } from 'rxjs';
import { ApplicationService } from '@core/application';
import { BreadcrumbService } from '@core/breadcrumb';

@Component({
  selector: 'page-customer-orders',
  templateUrl: 'customer-orders.component.html',
  styleUrls: ['customer-orders.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomerOrdersComponent implements OnInit, OnDestroy {
  private subs = new Subscription();

  customer$: Observable<CustomerDTO>;

  skip$ = new BehaviorSubject<number>(0);
  orders$ = new BehaviorSubject<OrderListItemDTO[]>([]);

  isLoading: boolean;
  hasCustomerCard$: Observable<boolean>;

  constructor(
    private activatedRoute: ActivatedRoute,
    private customerDetailsService: CrmCustomerService,
    private omsService: DomainOmsService,
    public application: ApplicationService,
    private breadcrumb: BreadcrumbService
  ) {}

  ngOnInit() {
    const customerId$ = this.activatedRoute.params.pipe(map((params) => Number(params['customerId'])));
    this.customer$ = customerId$.pipe(
      switchMap((customerId) => this.customerDetailsService.getCustomer(customerId, 2)),
      map(({ result }) => result)
    );

    const customerFeatures$ = this.customer$.pipe(
      map((customer: CustomerDTO) => Object.values(customer.features).filter((f) => f.enabled))
    );
    this.hasCustomerCard$ = customerFeatures$.pipe(map((features) => !!features.find((feature) => feature.description === 'Kundenkarte')));

    this.subs.add(
      combineLatest([this.customer$, this.skip$])
        .pipe(
          tap(() => (this.isLoading = true)),
          switchMap(([customer, skip]) => this.omsService.getOrderItemsByCustomerNumber(customer.customerNumber, skip)),
          shareReplay(),
          withLatestFrom(this.orders$)
        )
        .subscribe(([newOrders, orders]) => {
          this.orders$.next([...orders, ...newOrders]);
          this.isLoading = false;
        })
    );

    this.createBreadcrumb();
  }

  async createBreadcrumb() {
    const customer = await this.customer$?.pipe(first()).toPromise();
    this.breadcrumb.addBreadcrumbIfNotExists({
      key: this.application.activatedProcessId,
      name: 'Bestellungen',
      path: `/kunde/${this.application.activatedProcessId}/customer/${customer?.id}/orders`,
      tags: ['customer', 'orders'],
      section: 'customer',
      params: {},
    });

    const crumbs = await this.breadcrumb
      .getBreadcrumbsByKeyAndTags$(this.application.activatedProcessId, ['customer', 'orders'])
      .pipe(first())
      .toPromise();

    for (const crumb of crumbs) {
      this.breadcrumb.removeBreadcrumbsAfter(crumb.id, ['customer']);
    }
  }

  ngOnDestroy() {
    this.subs.unsubscribe();
  }

  async fetchOrders() {
    const orders = await this.orders$.pipe(first()).toPromise();
    this.skip$.next(orders.length);
  }

  reachEnd() {
    this.fetchOrders();
  }
}
