import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { OrderItemListItemDTO } from '@swagger/oms';
import { UiFilter } from '@ui/filter';
import { debounce, isEqual } from 'lodash';
import { combineLatest, Subscription } from 'rxjs';
import { debounceTime, first, map } from 'rxjs/operators';
import { GoodsOutSearchStore } from '../goods-out-search.store';

@Component({
  selector: 'page-goods-out-search-main',
  templateUrl: 'goods-out-search-main.component.html',
  styleUrls: ['goods-out-search-main.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GoodsOutSearchMainComponent implements OnInit, OnDestroy {
  filter$ = this._goodsOutSearchStore.filter$;

  loading$ = this._goodsOutSearchStore.fetching$;

  message: string;

  lastProcessId: number | undefined;

  private _subscriptions = new Subscription();

  get processId() {
    return +this._activatedRoute.snapshot.data.processId;
  }

  processId$ = this._activatedRoute.data.pipe(map((data) => +data.processId));

  constructor(
    private _goodsOutSearchStore: GoodsOutSearchStore,
    private _cdr: ChangeDetectorRef,
    private _router: Router,
    private _activatedRoute: ActivatedRoute,
    private _breadcrumb: BreadcrumbService
  ) {}

  ngOnInit() {
    this._subscriptions.add(
      this._goodsOutSearchStore.filter$.subscribe((f) => {
        this._cdr.markForCheck();
      })
    );

    this._subscriptions.add(
      combineLatest([this.processId$, this._activatedRoute.queryParams])
        .pipe(debounceTime(50))
        .subscribe(([processId, queryParams]) => {
          if (!isEqual(queryParams, this._goodsOutSearchStore.filter?.getQueryParams())) {
            this._goodsOutSearchStore.resetFilter(queryParams);
          }
          this.removeBreadcrumbs(processId);
        })
    );
  }

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

  async removeBreadcrumbs(processId: number) {
    const resultCrumbs = await this._breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['goods-out', 'results']).pipe(first()).toPromise();
    const detailsCrumbs = await this._breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['goods-out', 'details']).pipe(first()).toPromise();

    const editCrumbs = await this._breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['goods-out', 'edit']).pipe(first()).toPromise();

    editCrumbs.forEach((crumb) => {
      this._breadcrumb.removeBreadcrumb(crumb.id, true);
    });

    resultCrumbs.forEach((crumb) => {
      this._breadcrumb.removeBreadcrumb(crumb.id, true);
    });

    detailsCrumbs.forEach((crumb) => {
      this._breadcrumb.removeBreadcrumb(crumb.id, true);
    });
  }

  async search() {
    await this.updateQueryParams(this.processId);
    this.message = undefined;

    this._goodsOutSearchStore.searchResult$.pipe(first()).subscribe((result) => {
      if (result.error) {
      } else {
        if (result.hits > 0) {
          if (result.hits === 1) {
            const orderItem = result.result[0];
            this._router.navigate([this.getDetailsPath(orderItem, this.processId)]);
          } else {
            this._router.navigate(['/kunde', this.processId, 'goods', 'out', 'results'], {
              queryParams: this._goodsOutSearchStore.filter.getQueryParams(),
            });
          }
        } else {
          this.message = 'keine Suchergebnisse';
        }
      }

      this._cdr.markForCheck();
    });

    this._goodsOutSearchStore.search({ clear: true });
  }

  async updateBreadcrumb(processId: number, params: Record<string, string>) {
    await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
      key: processId,
      name: 'Warenausgabe',
      path: `/kunde/${processId}/goods/out`,
      tags: ['goods-out', 'main', 'filter'],
      section: 'customer',
      params,
    });
  }

  async updateQueryParams(processId: number) {
    const queryParams = { ...this._goodsOutSearchStore.filter?.getQueryParams() };
    queryParams.main_qs = queryParams.main_qs ?? '';
    await this._router.navigate([], { queryParams });
    this.updateBreadcrumb(processId, queryParams);
  }

  getDetailsPath(item: OrderItemListItemDTO, processId: number) {
    return item?.compartmentCode
      ? `/kunde/${processId}/goods/out/details/compartment/${encodeURIComponent(item?.compartmentCode)}/${item?.processingStatus}`
      : `/kunde/${processId}/goods/out/details/order/${encodeURIComponent(item?.orderNumber)}/${item?.processingStatus}`;
  }

  queryChangeDebounce = debounce(() => this.updateQueryParams(this.processId), 500);
}
