import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { KeyValueDTOOfStringAndString, OrderItemListItemDTO } from '@swagger/oms';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
import { UiScrollContainerComponent } from '@ui/scroll-container';
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
import { first, map, shareReplay, takeUntil } from 'rxjs/operators';
import { GoodsInRemissionPreviewStore } from './goods-in-remission-preview.store';
import { Config } from '@core/config';
import { ToastService } from '@core/toast';

@Component({
  selector: 'page-goods-in-remission-preview',
  templateUrl: 'goods-in-remission-preview.component.html',
  styleUrls: ['goods-in-remission-preview.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [GoodsInRemissionPreviewStore],
})
export class GoodsInRemissionPreviewComponent implements OnInit, OnDestroy {
  @ViewChild(UiScrollContainerComponent) scrollContainer: UiScrollContainerComponent;

  private _scrollPosition: number;

  items$ = this._store.results$;

  itemLength$ = this.items$.pipe(map((items) => items?.length));

  hits$ = this._store.hits$;

  loading$ = this._store.fetching$.pipe(shareReplay());

  changeActionLoader$ = new BehaviorSubject<boolean>(false);

  listEmpty$ = combineLatest([this.loading$, this.hits$]).pipe(
    map(([loading, hits]) => !loading && hits === 0),
    shareReplay()
  );

  actions$ = this.items$.pipe(map((items) => items[0]?.actions));

  private _onDestroy$ = new Subject<void>();

  byBuyerNumberFn = (item: OrderItemListItemDTO) => item.buyerNumber;

  byOrderNumberFn = (item: OrderItemListItemDTO) => item.orderNumber;

  byProcessingStatusFn = (item: OrderItemListItemDTO) => item.processingStatus;

  byCompartmentCodeFn = (item: OrderItemListItemDTO) => item.compartmentCode;

  constructor(
    private _breadcrumb: BreadcrumbService,
    private _store: GoodsInRemissionPreviewStore,
    private _route: ActivatedRoute,
    private _router: Router,
    private _modal: UiModalService,
    private _config: Config,
    private _toast: ToastService
  ) {}

  ngOnInit(): void {
    this.initInitialSearch();
    this.createBreadcrumb();
    this.removeBreadcrumbs();
  }

  ngOnDestroy(): void {
    this._onDestroy$.next();
    this._onDestroy$.complete();
    this.updateBreadcrumb();
  }

  async createBreadcrumb() {
    await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
      key: this._config.get('process.ids.goodsIn'),
      name: 'Abholfachremissionsvorschau',
      path: '/filiale/goods/in/preview',
      section: 'branch',
      tags: ['goods-in', 'preview'],
    });
  }

  async updateBreadcrumb() {
    const crumbs = await this._breadcrumb
      .getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), ['goods-in', 'preview'])
      .pipe(first())
      .toPromise();
    for (const crumb of crumbs) {
      this._breadcrumb.patchBreadcrumb(crumb.id, {
        name: crumb.name,
        params: { scroll_position: this.scrollContainer?.scrollPos },
      });
    }
  }

  async removeBreadcrumbs() {
    const detailsCrumbs = await this._breadcrumb
      .getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), ['goods-in', 'details'])
      .pipe(first())
      .toPromise();
    const editCrumbs = await this._breadcrumb
      .getBreadcrumbsByKeyAndTags$(this._config.get('process.ids.goodsIn'), ['goods-in', 'edit'])
      .pipe(first())
      .toPromise();

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

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

  initInitialSearch() {
    if (this._store.hits === 0) {
      this._store.searchResult$.pipe(takeUntil(this._onDestroy$)).subscribe(async (result) => {
        await this.createBreadcrumb();

        if (this._scrollPosition) {
          this.scrollContainer?.scrollTo(Number(this._scrollPosition ?? 0));
          this._scrollPosition = undefined;
        }
      });
    }

    this._scrollPosition = this._route.snapshot.queryParams?.scroll_position;
    this._store.search();
  }

  async navigateToRemission() {
    await this._router.navigate(['/filiale/remission']);
  }

  navigateToDetails(orderItem: OrderItemListItemDTO) {
    const customerNumber = orderItem.buyerNumber;
    const orderNumber = orderItem.orderNumber;
    const processingStatus = orderItem.processingStatus;
    const orderItemId = orderItem.orderItemSubsetId;

    this._router.navigate([
      `/filiale/goods/in/details/customer/${encodeURIComponent(customerNumber)}/order/${encodeURIComponent(
        orderNumber
      )}/item/${orderItemId}/${processingStatus}`,
    ]);
  }

  async handleAction(action: KeyValueDTOOfStringAndString) {
    this.changeActionLoader$.next(true);

    try {
      const response = await this._store.createRemissionFromPreview().pipe(first()).toPromise();

      if (!response?.dialog) {
        this._toast.create({
          title: 'Abholfachremission',
          text: response?.message,
        });
      }

      await this.navigateToRemission();
    } catch (error) {
      this._modal.open({
        content: UiErrorModalComponent,
        data: error,
      });
      console.error(error);
    }

    this.changeActionLoader$.next(false);
  }
}
