import { Injectable } from '@angular/core';
import { Observable, fromEvent, Subject, ReplaySubject } from 'rxjs';
import { map } from 'rxjs/operators';
import { WindowRef } from './window-ref.service';
import { ScanRequestType } from './scan-request.type';
import { Platform } from '@angular/cdk/platform';

/**
 * @deprecated This service is deprecated and will be removed in future versions.
 */
@Injectable({
  providedIn: 'root',
})
export class NativeContainerService {
  private wm: Observable<any>;
  public windowMessages = new Subject<any>();

  private webViewEventRecieved = false;

  private _init$ = new ReplaySubject<boolean>(1);

  get isNative() {
    return this.webViewEventRecieved;
  }

  constructor(
    private windowRef: WindowRef,
    private _platform: Platform,
  ) {
    this.defineWindowCallback();

    this.wm = fromEvent(this.windowRef.nativeWindow, 'message').pipe(
      map((e: MessageEvent) => {
        return e.data;
      }),
    );

    this.wm.subscribe((data) => {
      if (data.status === 'INIT') {
        this.webViewEventRecieved = true;
        this._init$.next(true);
      }
      this.windowMessages.next(data);
    });
  }

  init() {
    return this._init$.asObservable();
  }

  public openScanner(scanRequestType: ScanRequestType) {
    const scanRequest = {
      [scanRequestType]: true,
    };

    this.sendMessage(scanRequest);

    return this.windowMessages.asObservable().pipe(map((message) => message as { status: string; data?: any }));
  }

  public sendMessage(message: any) {
    this.windowRef.nativeWindow.postMessage({ status: 'IN_PROGRESS', data: 'Scan Started' }, '*');

    try {
      (this.windowRef.nativeWindow as any).webkit.messageHandlers.scanRequest.postMessage(message);
    } catch (error) {
      this.windowRef.nativeWindow.postMessage({ status: 'ERROR', data: 'Not a WebView' }, '*');
      this.windowRef.nativeWindow.postMessage(message, '*');
    }
  }

  private defineWindowCallback() {
    if (this.windowRef.nativeWindow['scanResults'] === undefined) {
      this.windowRef.nativeWindow['scanResults'] = (result) => window.postMessage(result, '*');
    }

    if (this.windowRef.nativeWindow['isRunningNative'] === undefined) {
      this.windowRef.nativeWindow['isRunningNative'] = (_) =>
        window.postMessage({ status: 'INIT', data: 'Is a WebView' }, '*');
    }

    // Try sending ping request, to invoke the containers isRunningNative event
    try {
      (this.windowRef.nativeWindow as any).webkit.messageHandlers.scanRequest.postMessage('PING');
    } catch (error) {
      this._init$.next(false);
      this.windowRef.nativeWindow.postMessage({ status: 'ERROR', data: 'Not a WebView' }, '*');
      this.windowRef.nativeWindow.postMessage('PING', '*');
    }
  }
}
