import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FormGroup, FormArray } from '@angular/forms';
import { ShelfNavigationService } from '../../shared/services';
import { filter, map, distinctUntilChanged, shareReplay, take, withLatestFrom, first } from 'rxjs/operators';
import { isNullOrUndefined } from 'util';
import { DatePipe } from '@angular/common';
import { OrderItemProcessingStatusValue } from '@swagger/oms';
import { ShelfEditFormService } from '../../services/shelf-edit-form.service';
import { ProcessingStatusOptionsPipe, ProcessingStatusPipe, PickUpDateOptionsToDisplayValuesPipe } from '../../pipes';
import { ErrorService } from 'apps/sales/src/app/core/error/component/error.service';
@Component({
  selector: 'app-shelf-edit-order',
  templateUrl: './shelf-edit-order.component.html',
  styleUrls: ['./shelf-edit-order.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShelfEditOrderComponent implements OnInit {
  // Form Information
  customerName: { firstName: string; lastName: string };
  form: FormGroup;
  items: FormArray;

  // Pipes for Mapping Values to display names
  processingStatusPipe = new ProcessingStatusPipe();
  processingStatusOptionsPipe = new ProcessingStatusOptionsPipe();
  dateOptionsPipe = new PickUpDateOptionsToDisplayValuesPipe();
  datePipe = new DatePipe('de');

  constructor(
    private activatedRoute: ActivatedRoute,
    protected formService: ShelfEditFormService,
    private shelfNavigationService: ShelfNavigationService,
    private errorService: ErrorService,
    private cdr: ChangeDetectorRef
  ) {}

  get orderNumber$() {
    return this.activatedRoute.params.pipe(
      filter((params) => !isNullOrUndefined(params)),
      map((params) => params.orderNumber),
      distinctUntilChanged(),
      shareReplay()
    );
  }

  get processingStatus$() {
    return this.activatedRoute.params.pipe(
      map((params) => Number(params.processingStatus) as OrderItemProcessingStatusValue),
      distinctUntilChanged(),
      shareReplay()
    );
  }

  ngOnInit() {
    this.loadOrderNumberAndInitForm();
  }

  async loadOrderNumberAndInitForm() {
    const orderNumber = await this.orderNumber$.pipe(take(1)).toPromise();
    const processingStatus = await this.processingStatus$.pipe(take(1)).toPromise();
    console.log('loadOrderNumberAndInitForm', {
      orderNumber,
      processingStatus,
    });
    this.populateFormData(orderNumber, processingStatus);
  }

  async onSubmit() {
    const orderNumber = await this.orderNumber$.pipe(first()).toPromise();
    const processingStatus = await this.processingStatus$.pipe(first()).toPromise();

    const submitResult = await this.formService.submit(this.form, processingStatus);

    if (submitResult.result) {
      this.shelfNavigationService.navigateBackToDetails({
        orderNumber,
        processingStatus: this.form.get('processingStatus').value || processingStatus,
      });
    }

    if (!submitResult.result) {
      this.showSubmitError({
        message: submitResult.message,
        code: submitResult.http ? submitResult.http.code : 500,
        invalidProperties: submitResult.errorReasons,
      });
    }
  }

  onAbortEdit() {
    return this.orderNumber$
      .pipe(take(1), withLatestFrom(this.processingStatus$))

      .subscribe(([orderNumber, processingStatus]) =>
        this.shelfNavigationService.navigateBackToDetails({
          orderNumber,
          processingStatus,
        })
      );
  }

  private async populateFormData(orderNumber: string, processingStatus: OrderItemProcessingStatusValue) {
    this.form = await this.formService.createFormByOrderNumber(orderNumber, processingStatus);

    this.items = this.formService.getItemsForm(orderNumber);
    this.customerName = this.formService.getCustomerName(orderNumber);
    this.cdr.detectChanges();
  }

  private showSubmitError(error: { message: string; code: number; invalidProperties: { [key: string]: string } }) {
    const invalidProperties = Object.values(error.invalidProperties).join(', ') || undefined;

    this.errorService.addErrors(error.code, error.message, invalidProperties);
  }
}
