import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectorRef, AfterViewInit } from '@angular/core';
import { Router } from '@angular/router';
import { Store, Select } from '@ngxs/store';
import { Observable, Subject, of } from 'rxjs';
import { takeUntil, catchError } from 'rxjs/operators';
import { CustomerInfoDTO } from '@swagger/crm';
import { CustomerCardScannerScanditComponent } from 'shared/lib/customer-card-scanner';
import { CustomerService } from 'apps/sales/src/app/core/services/customer.service';
import { WindowRef } from 'apps/sales/src/app/core/services/window-ref.service';
import { ChangeCurrentRoute, AddProcess, CustomerOrdersVisited, AddCustomerSearch } from '../../../../core/store/actions/process.actions';
import { Process } from '../../../../core/models/process.model';
import { Breadcrumb } from '../../../../core/models/breadcrumb.model';
import { AddBreadcrumb } from '../../../../core/store/actions/breadcrumb.actions';
import { ProcessSelectors } from '../../../../core/store/selectors/process.selectors';
import { CustomerCardManualEntryComponent } from '../../components/customer-card-manual-entry/customer-card-manual-entry.component';
import { CustomerCardSearchEmptyModalComponent } from '../../components/customer-card-search-empty-modal/customer-card-search-empty-modal.component';
import { CustomerCardSearchErrorModalComponent } from '../../components/customer-card-search-error-modal/customer-card-search-error-modal.component';
import { ErrorService } from 'apps/sales/src/app/core/error/component/error.service';

@Component({
  selector: 'app-customer-card-barcode-search',
  templateUrl: 'customer-card-barcode-search.component.html',
  styleUrls: ['customer-card-barcode-search.component.scss'],
})
export class CustomerCardBarcodeSearchComponent implements OnInit, OnDestroy, AfterViewInit {
  @ViewChild('scanner') scanner: CustomerCardScannerScanditComponent;
  @ViewChild('manualentry') manualentry: CustomerCardManualEntryComponent;
  @ViewChild('searchCardEmptyModal') searchCardEmptyModal: CustomerCardSearchEmptyModalComponent;
  @ViewChild('searchCardErrorModal') searchCardErrorModal: CustomerCardSearchErrorModalComponent;
  @Select(ProcessSelectors.getProcesses) processes$: Observable<Process[]>;
  processes: Process[] = [];
  destroy$ = new Subject();
  showScanner = false;
  isWebView: boolean;
  private webViewDetected = false;
  private webViewEventRecieved = false;

  constructor(
    private store: Store,
    private router: Router,
    protected customerService: CustomerService,
    private cdrf: ChangeDetectorRef,
    private windowRef: WindowRef,
    private errorService: ErrorService
  ) {}

  ngOnInit() {
    this.processes$.pipe(takeUntil(this.destroy$)).subscribe((p: Process[]) => (this.processes = p));
  }

  ngAfterViewInit(): void {
    this.isWebView = this.isUiWebview();
    this.cdrf.detectChanges();
  }

  isUiWebview() {
    const navigator = this.windowRef.nativeWindow.navigator as Navigator;
    const standalone = (navigator as any).standalone,
      userAgent = navigator.userAgent.toLowerCase(),
      safari = /safari/.test(userAgent),
      ios = /iphone|ipod|ipad/.test(userAgent);

    this.webViewDetected = ios && !standalone && !safari;
    return this.webViewDetected || this.webViewEventRecieved;
  }

  triggerSearch(barcode) {
    if (!this.processes || this.processes.length < 1) {
      this.createProcess();
    }

    this.customerService
      .validateScannedCustomer(barcode)
      .pipe(takeUntil(this.destroy$))
      .subscribe(
        (customers: CustomerInfoDTO[]) => {
          if (Array.isArray(customers) && customers.length > 0) {
            this.store.dispatch(
              new AddBreadcrumb(
                {
                  name: (barcode.length > 12 ? barcode.substring(0, 12) + '...' : barcode) + ` (${customers.length} Ergebnisse)`,
                  path: '/customer/results',
                  queryParams: { scan: true },
                },
                'customer'
              )
            );
            this.store.dispatch(
              new AddCustomerSearch({
                query: barcode,
                skip: 0,
                take: 5,
                firstLoad: true,
              })
            );
            this.store.dispatch(new ChangeCurrentRoute('/customer/results'));
            this.router.navigate(['/customer/results'], { queryParams: { scan: true } });
          } else {
            this.scanner.scanToggle();
            this.searchCardEmptyModal.openDialog();
          }
        },
        (e) => {
          this.errorService.addErrors(e.status, e.message, undefined);
        }
      );
  }

  details(data: string): void {
    this.store.dispatch(new CustomerOrdersVisited(false));
    const currentRoute = '/customer/edit/' + data;
    this.store.dispatch(new ChangeCurrentRoute(currentRoute));
    this.router.navigate([currentRoute], { queryParams: { type: 'scan' } });
  }

  createProcess() {
    const newProcess = <Process>{
      id: 1,
      name: 'Vorgang 1',
      currentRoute: '/customer/search',
    };

    this.store.dispatch(new AddProcess(newProcess));
    this.store.dispatch(
      new AddBreadcrumb(
        <Breadcrumb>{
          name: 'Kundenkarte scannen',
          path: '/customer/search',
        },
        'customer'
      )
    );
  }

  toggleScan() {
    this.showScanner = !this.showScanner;
  }

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

  openScanner() {
    this.scanner.openNativeScanner();
  }

  openManualEntry() {
    this.manualentry.openDialog();
  }
}
