import { Component, ChangeDetectionStrategy, OnDestroy, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { CacheService } from '@core/cache';
import { Config } from '@core/config';
import { DomainRemissionService } from '@domain/remission';
import { ReturnItemDTO } from '@swagger/remi';
import { UiErrorModalComponent, UiMessageModalComponent, UiModalRef, UiModalService } from '@ui/modal';
import { BehaviorSubject, Subject } from 'rxjs';
import { first, map, takeUntil } from 'rxjs/operators';
import { AddProductModalData } from './add-product-modal.data';

@Component({
  selector: 'page-add-product-modal',
  templateUrl: 'add-product-modal.component.html',
  styleUrls: ['add-product-modal.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddProductModalComponent implements OnInit, OnDestroy {
  private _onDestroy$ = new Subject();

  get processId() {
    return this._config.get('process.ids.remission');
  }

  message$ = new BehaviorSubject<string>(undefined);

  item: ReturnItemDTO;

  form: FormGroup;

  selectedReason: string;

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

  get title() {
    return [this.item.product.contributors, this.item.product.name].filter((f) => !!f).join(' - ');
  }

  get returnReasons$() {
    return this._remiService.getReturnReasons().pipe(map((reasons) => reasons.map((r) => r.value)));
  }

  constructor(
    private _modalRef: UiModalRef<boolean, AddProductModalData>,
    private _remiService: DomainRemissionService,
    private _modal: UiModalService,
    private _config: Config,
    private _cache: CacheService
  ) {
    this.item = this._modalRef.data.item;

    this.form = new FormGroup({
      quantity: new FormControl(this.item.predefinedReturnQuantity),
    });

    this.form
      .get('quantity')
      .valueChanges.pipe(takeUntil(this._onDestroy$))
      .subscribe((quantity) => (quantity === 0 ? this._modalRef.close() : ''));
  }

  reasonChanged(reason: string) {
    this.selectedReason = reason;
    this.message$.next(undefined);
    this.checkCanAdd();
  }

  ngOnInit() {
    this.checkCanAdd();

    this.form.valueChanges.pipe(takeUntil(this._onDestroy$)).subscribe(() => this.checkCanAdd());
  }

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

  async checkCanAdd() {
    try {
      const canAdd = await this._remiService
        .canAddReturnItem({
          ...this.item,
          returnReason: this.selectedReason,
          predefinedReturnQuantity: this.form.value.quantity,
        })
        .pipe(first())
        .toPromise();

      if (canAdd.failed?.length > 0) {
        const message = canAdd.failed.map((f) => Object.values(f.invalidProperties).join('\n')).join('\n');
        this.message$.next(message);
      } else {
        this.canAdd$.next(true);
      }
    } catch (err) {
      this._modal.open({
        content: UiErrorModalComponent,
        data: err,
      });
    }
  }

  async addClick() {
    if (!this.selectedReason) {
      this.message$.next('Bitte wählen Sie einen Remigrund');
      return;
    }

    try {
      const result = await this._remiService
        .addProductToRemit(this.item, this.selectedReason, this.form.value.quantity)
        .pipe(first())
        .toPromise();

      if (result.failed?.length > 0) {
        const message = result.failed.map((f) => Object.values(f.invalidProperties).join('\n')).join('\n');
        this._modal.open({
          content: UiMessageModalComponent,
          data: { message },
          // title: 'Artikel kann nicht remittiert werden',
        });
      } else {
        this._cache.delete({ processId: String(this.processId) });
        this._modalRef.close(true);
      }
    } catch (err) {
      this._modalRef.close();
      this._modal.open({
        content: UiErrorModalComponent,
        data: err,
      });
    }
  }
}
