import { Component, OnInit, ChangeDetectionStrategy, ViewChild } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
import { Observable, of } from 'rxjs';
import { filter, catchError, map, switchMap, take, first } from 'rxjs/operators';
import { RemissionScanProductInvalidBarcodeComponent } from '../../../components/remission-scan-product-invalid-barcode';
import { isNullOrUndefined } from 'util';
import { AppService } from '@sales/core-services';
import { RemissionService, ShippingDocument, RemissionProcess } from '@isa/remission';
import { ErrorService } from 'apps/sales/src/app/core/error/component/error.service';
import { SetRemissionShippingDocument } from 'apps/sales/src/app/core/store/actions/remission.actions';
import { NativeContainerService } from 'shared/public_api';

@Component({
  selector: 'app-shipping-document-creation',
  templateUrl: './shipping-document-creation.component.html',
  styleUrls: ['./shipping-document-creation.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShippingDocumentCreationComponent implements OnInit {
  showScanningButton$: Observable<boolean>;

  @Select(RemissionSelectors.getRemissionShippingDocument)
  shippingDocument$: Observable<ShippingDocument>;
  @Select(RemissionSelectors.getRemissionShippingDocumentstatus)
  isShippingDocumentCreated$: Observable<boolean>;
  @Select(RemissionSelectors.getRemissionProcess)
  currentRemissionProcess$: Observable<RemissionProcess>;
  @Select(RemissionSelectors.allowScanningShippingDocument)
  enableScan$: Observable<boolean>;

  @ViewChild('invalidBarcodeDialog')
  invalidBarcodeDialog: RemissionScanProductInvalidBarcodeComponent;

  constructor(
    private appService: AppService,
    private nativeService: NativeContainerService,
    private remissionService: RemissionService,
    private errorService: ErrorService,
    private store: Store
  ) {}

  ngOnInit() {
    this.showScanningButton$ = this.enableScan$.pipe(
      map((allowScan) => !!allowScan && this.appService.isIPadEnv() && this.nativeService.isUiWebview())
    );
  }

  shippingDocumentWithGeneratedId() {
    this.createShippingDocument();
  }

  shippingDocumentScanned(receiptNumber: string) {
    if (receiptNumber) {
      this.createShippingDocument(receiptNumber);
    } else {
      this.invalidBarcodeDialog.openDialog();
    }
  }

  createShippingDocument(receiptNumber?: string) {
    let params: {
      remissionProcessId: number;
      receiptNumber?: string;
    };

    this.currentRemissionProcess$
      .pipe(
        map((process) => process.id),
        first(),
        switchMap((remissionProcessId) => {
          params = {
            remissionProcessId,
          };
          if (receiptNumber) {
            params = { ...params, receiptNumber };
          }

          return this.remissionService.createShippingDocument(params).pipe(
            filter((shippingDocument) => !isNullOrUndefined(shippingDocument)),
            catchError((error) => {
              const invalidProperties =
                error.invalidProperties && Object.keys(error.invalidProperties).length > 0
                  ? JSON.stringify(error.invalidProperties)
                  : undefined;
              this.errorService.addErrors(error.httpError.code, error.message, JSON.stringify(invalidProperties));
              return of(undefined);
            }),
            take(1)
          );
        })
      )
      .subscribe(
        (shippingDocument: ShippingDocument) =>
          !!shippingDocument && this.store.dispatch(new SetRemissionShippingDocument(shippingDocument))
      );
  }
}
