import { Injectable } from '@angular/core';
import { Observable, Subscriber } from 'rxjs';
import { ScanAdapter } from '../scan-adapter';
import { Overlay } from '@angular/cdk/overlay';

import { configure } from 'scandit-web-datacapture-core';
import { barcodeCaptureLoader } from 'scandit-web-datacapture-barcode';

// import { ScanditModalComponent } from './scandit-modal';
import { Config } from '@core/config';
import { ComponentPortal } from '@angular/cdk/portal';
import { ScanditOverlayComponent } from './scandit-overlay.component';
import { EnvironmentService } from '@core/environment';
import { injectNetworkStatus$ } from 'apps/isa-app/src/app/services/network-status.service';
import { toSignal } from '@angular/core/rxjs-interop';

@Injectable()
export class ScanditScanAdapter implements ScanAdapter {
  readonly name = 'Scandit';

  private $networkStatus = toSignal(injectNetworkStatus$());

  constructor(
    private readonly _config: Config,
    private _overlay: Overlay,
    private _environmentService: EnvironmentService,
  ) {}

  async init(): Promise<boolean> {
    const enabled =
      localStorage.getItem('scandit_scan_adapter_enabled') === 'true';

    if (enabled || this._environmentService.isTablet()) {
      try {
        await configure({
          licenseKey: this._config.get('licence.scandit'),
          libraryLocation: new URL('scandit', document.baseURI).toString(),
          moduleLoaders: [barcodeCaptureLoader()],
        });

        return true;
      } catch (error) {
        console.error('ScanditScanAdapter.init', error);
      }
    }

    return false;
  }

  scan(): Observable<string> {
    return new Observable((observer) => {
      if (this.$networkStatus() === 'offline') {
        observer.error(new Error('No network connection'));
        return;
      }

      const overlay = this.createOverlay();

      const portal = this.createPortal();

      const ref = overlay.attach(portal);

      const sub = new Subscriber();

      const complete = () => {
        overlay.detach();
        ref.destroy();
        sub.unsubscribe();
        sub.complete();
        observer.complete();
      };

      sub.add(
        overlay.backdropClick().subscribe(() => {
          complete();
        }),
      );

      ref.instance.onScan((code) => {
        observer.next(code);
        complete();
      });

      ref.instance.onClose(() => {
        complete();
      });

      return complete;
    });
  }

  createOverlay() {
    const overlay = this._overlay.create({
      positionStrategy: this._overlay
        .position()
        .global()
        .centerHorizontally()
        .centerVertically(),
      hasBackdrop: true,
    });

    return overlay;
  }

  createPortal() {
    const portal = new ComponentPortal(ScanditOverlayComponent);

    return portal;
  }
}
