import { Component, OnInit, Input, ViewChild, OnDestroy, Output, EventEmitter } from '@angular/core';
import { Store, Select } from '@ngxs/store';
import { RemissionService, ShippingDocument } from '@isa/remission';
import { take, filter, takeUntil, map } from 'rxjs/operators';
import { isNullOrUndefined } from 'util';
import {
  SetRemissionShippingDocument,
  DeleteRemissionShippingDocument,
  SetRemissionFinishedProcessStatus,
  SetRemissionProcess,
  ResetRemissionState,
} from 'apps/sales/src/app/core/store/actions/remission.actions';
import { RemissionSelectors } from 'apps/sales/src/app/core/store/selectors/remission.selectors';
import { Observable, Subject } from 'rxjs';
// tslint:disable-next-line: max-line-length
import { RemissionConfirmDeleteShippingDocumentDialogComponent } from '../remission-confirm-delete-shipping-document-dialog/remission-confirm-delete-shipping-document-dialog.component';
import { AddBreadcrumb, ResetBreadcrumbsTo } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { Router } from '@angular/router';
import { SetBranchProcessCurrentPath } from 'apps/sales/src/app/core/store/actions/branch-process.actions';
import { RemissionFinishingProcessStatus } from '../../models/remission-finishing-process-status.enum';

@Component({
  selector: 'app-remission-shipping-document',
  templateUrl: './remission-shipping-document.component.html',
  styleUrls: ['./remission-shipping-document.component.scss'],
})
export class RemissionShippingDocumentComponent implements OnInit, OnDestroy {
  @Input() shippingDocument: ShippingDocument;
  @Input() selectedSupplier: string;
  @Input() shippingDocumentId: number;
  @Input() remissionProcessId: number;
  @Select(RemissionSelectors.getRemissionShippingDocumentstatus)
  shippingDocumentStatus$: Observable<boolean>;

  @Output() updateShippingDocument = new EventEmitter<void>();

  @ViewChild('remissionConfirmDeleteDialog')
  remissionConfirmDeleteDialog: RemissionConfirmDeleteShippingDocumentDialogComponent;

  destroy$ = new Subject();

  constructor(private store: Store, private router: Router, private remissionService: RemissionService) {}

  ngOnInit() {}

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

  private hasProducts(shippingDocument: ShippingDocument): boolean {
    return !!shippingDocument.products.length;
  }

  deleteShippingDocument() {
    if (this.hasProducts(this.shippingDocument)) {
      this.remissionConfirmDeleteDialog.openDialog();
    } else {
      this.remissionService
        .deleteShippingDocument({
          remissionProcessId: this.remissionProcessId,
          shippingDocumentId: this.shippingDocumentId,
        })
        .pipe(
          takeUntil(this.destroy$),
          map((response) => response.result)
        )
        .subscribe((result) => this.handleDeleteResult(result));
    }
  }

  confirmDeleteShippingDocument() {
    this.remissionService
      .deleteShippingDocument({
        remissionProcessId: this.remissionProcessId,
        shippingDocumentId: this.shippingDocumentId,
      })
      .pipe(
        takeUntil(this.destroy$),
        map((response) => response.result)
      )
      .subscribe(this.handleDeleteResult);
  }

  private handleDeleteResult = (result: { deleted: boolean; completedRemissionsExist: boolean }) => {
    if (result.deleted) {
      this.store.dispatch(new DeleteRemissionShippingDocument(this.remissionProcessId));
    }

    if (result.completedRemissionsExist) {
      this.markRemissionCompleted();
      return this.navigateToCompleteRemissionPage();
    }

    this.store.dispatch(new ResetRemissionState());
    return this.navigateToStartPage();
  };

  navigateToStartPage() {
    const path = '/remission/create';
    this.store.dispatch(
      new ResetBreadcrumbsTo(
        {
          path: path,
          name: 'Remission',
        },
        'remission'
      )
    );

    this.router.navigate([path]).then((_) => this.store.dispatch(new SetBranchProcessCurrentPath(path, true)));
  }

  private markRemissionCompleted() {
    this.store.dispatch(new SetRemissionFinishedProcessStatus(RemissionFinishingProcessStatus.containerScanned));
  }

  private navigateToCompleteRemissionPage() {
    const path = '/remission/finish';
    this.store.dispatch(
      new AddBreadcrumb(
        {
          path: path,
          name: 'Wannennummer',
        },
        'remission'
      )
    );
    this.router.navigate([path]);
    this.store.dispatch(new SetBranchProcessCurrentPath(path));
  }

  continueExistingShippingDocument() {
    return this.store.selectOnce(RemissionSelectors.getRemissionShippingDocument);
  }

  createShippingDocument$(): Observable<ShippingDocument> {
    let params: {
      remissionProcessId: number;
      shippingDocumentId?: number;
    };
    if (this.shippingDocumentId) {
      params = {
        remissionProcessId: this.remissionProcessId,
        shippingDocumentId: this.shippingDocumentId,
      };
    } else {
      params = { remissionProcessId: this.remissionProcessId };
    }

    return this.remissionService.createShippingDocument(params).pipe(
      filter((data) => !isNullOrUndefined(data)),
      take(1)
    );
  }
}
