import { Subject } from 'rxjs';

import {
  Component,
  OnDestroy,
  OnInit,
  Input,
  EventEmitter,
  ChangeDetectorRef,
  Output,
  HostListener,
  QueryList,
  ViewChildren,
} from '@angular/core';
import { ModalService, DropdownComponent } from '@libs/ui';
import { OrderItemDTO } from '@swagger/oms';
import { mapToIterable } from 'apps/sales/src/app/core/utils/app.utils';

@Component({
  selector: 'app-shelf-partial-collection-modal',
  templateUrl: './partial-collection-modal.component.html',
  styleUrls: ['./partial-collection-modal.component.scss'],
})
export class ShelfPartialCollectionModalComponent implements OnInit, OnDestroy {
  id = 'partial-collection-modal';
  destroy$ = new Subject();
  error = false;
  errorMessage = 'Bitte wählen Sie mindestens einen Artikel aus.';
  top = 0;
  collectOptions: { [key: string]: number[] } = {};
  selectedCollectOptions: { [key: string]: number } = {};

  @ViewChildren('quantityDD') quantityDD: QueryList<DropdownComponent>;

  @Output() close = new EventEmitter();
  @Output() collect: EventEmitter<{ [key: string]: number }> = new EventEmitter();

  @Input() set productsList(val: OrderItemDTO[]) {
    this.products = val;
  }

  products: OrderItemDTO[];

  @Input() compartmentCode: string;

  get title() {
    if (this.products && this.products.length > 1) {
      return 'Welche Artikel möchten Sie abholen?';
    } else if (this.products && this.products.length === 1) {
      return 'Wie viele Exemplare möchten Sie abholen?';
    }
  }

  get sum() {
    let sum = 0;
    if (this.products) {
      this.products.forEach((product) => {
        if (
          product &&
          product.orderItemNumber &&
          this.selectedCollectOptions[product.orderItemNumber] &&
          product.grossPrice &&
          product.grossPrice.value &&
          product.grossPrice.value.value
        ) {
          const productSum = product.grossPrice.value.value * this.selectedCollectOptions[product.orderItemNumber];
          sum += productSum;
        }
      });
    }
    return sum;
  }

  constructor(private modalService: ModalService, private cdrf: ChangeDetectorRef) {}

  getCollectOptions(orderItemNumber: string) {
    return this.collectOptions[orderItemNumber];
  }

  getSelectedCollectOptions(orderItemNumber: string) {
    return this.selectedCollectOptions[orderItemNumber];
  }

  ngOnInit() {
    this.initialize();
  }

  public initialize() {
    if (this.products) {
      const totalItems = this.products.length;
      this.products.forEach((product) => {
        const numberOfItems =
          product && product.subsetItems && product.subsetItems.length > 0
            ? product.subsetItems
                .map((subsetItem) => {
                  if (subsetItem && subsetItem.data && subsetItem.data.quantity) {
                    return subsetItem.data.quantity;
                  }
                  return 0;
                })
                .reduce((q1, q2) => q1 + q2)
            : 0;
        this.collectOptions[product.orderItemNumber] = new Array(numberOfItems + 1).fill(0).map((_, index) => index);
        if (totalItems === 1) {
          this.selectedCollectOptions[product.orderItemNumber] = 1;
        } else if (totalItems > 1) {
          this.selectedCollectOptions[product.orderItemNumber] = 0;
          this.error = true;
        }
      });
      this.cdrf.detectChanges();
    }
  }

  public reloadOrderItem(orderItem: OrderItemDTO[]) {
    this.products = orderItem;
  }

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

  updateQuantity(quantity: number, orderItemNumber: string) {
    this.selectedCollectOptions[orderItemNumber] = quantity;
    this.validateQuantity();
    this.cdrf.detectChanges();
  }

  validateQuantity() {
    const quantityTotal = mapToIterable(this.selectedCollectOptions).reduce((q1: number, q2: number) => q1 + q2);
    if (quantityTotal === 0) {
      this.error = true;
    } else {
      this.error = false;
    }
  }

  // COMMON
  openDialog() {
    this.modalService.open(this.id);
  }

  closeDialog() {
    this.close.emit(true);
    this.modalService.close(this.id);
  }

  itemsConfirmed() {
    this.collect.emit(this.selectedCollectOptions);
    this.closeDialog();
  }

  @HostListener('window:scroll', ['$event'])
  scrollHandler() {
    this.quantityDD.forEach((dd) => {
      if (dd) {
        dd.setTop(document.getElementById('scrolling-container').scrollTop);
        dd.closeDropdown();
      }
    });
  }
}
