import { Component, EventEmitter, OnInit, ViewChild, OnDestroy, Output } from '@angular/core';
import { BarcodeFormat, Result } from '@zxing/library';
import { ZXingScannerComponent } from '@zxing/ngx-scanner';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-barcode-scanner',
  templateUrl: 'barcode-scanner.component.html',
  styleUrls: ['barcode-scanner.component.scss'],
})
export class BarcodeScannerComponent implements OnInit, OnDestroy {
  @Output() scan: EventEmitter<string> = new EventEmitter();
  @ViewChild('scanner', { static: true }) scanner: ZXingScannerComponent;

  allowedFormats = [BarcodeFormat.QR_CODE, BarcodeFormat.EAN_13, BarcodeFormat.CODE_128, BarcodeFormat.UPC_A];
  enabled = false;
  debugMode = true;
  code = '';
  hasDevices;
  availableDevices: MediaDeviceInfo[];
  currentDevice: MediaDeviceInfo;
  hasPermission;
  destroy$ = new Subject();

  ngOnInit() {
    this.scanner.camerasNotFound.pipe(takeUntil(this.destroy$)).subscribe(() => (this.hasDevices = false));
    this.scanner.scanComplete.pipe(takeUntil(this.destroy$)).subscribe((result) => this.scanSuccess(result));
    this.scanner.permissionResponse.pipe(takeUntil(this.destroy$)).subscribe((perm: boolean) => {
      this.hasPermission = perm;
    });
  }

  scanSuccess(result: Result) {
    this.code = result.getText();
    this.scan.next(this.code);
    this.enabled = false;
  }

  camerasFoundHandler(devices: MediaDeviceInfo[]) {
    this.hasDevices = true;
    this.availableDevices = devices;

    this.currentDevice = devices[0];

    for (const device of devices) {
      this.scanner.changeDevice(device);
      this.currentDevice = device;
      this.scanner.scan(device.deviceId);
      break;
    }
  }

  scanErrorHandler($event) {
    console.error($event);
  }

  scanFailureHandler($event) {
    console.error($event);
  }

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