import { Injectable } from '@angular/core';
import { Observable, Subject, of } from 'rxjs';
import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { ipcRenderer } from 'electron';

import { MenuEvent } from '../type';
import { LaunchState } from '../model';
import { LaunchService } from './launch.service';

@Injectable({
  providedIn: 'root'
})
export class ElectronProxyService {
  private menuSubject: Subject<MenuEvent>;

  public constructor(
    private store: Store<any>,
    private launchService: LaunchService
  ) {
    this.menuSubject = new Subject<MenuEvent>();

    this.bindIpcEventHandlers();
  }

  public menuObservable(): Observable<MenuEvent> {
    return this.menuSubject.asObservable();
  }

  private bindIpcEventHandlers(): void {
    ipcRenderer.on(
      'menu-event',
      (event: Electron.IpcMessageEvent, { name }: { name: MenuEvent }) => {
        console.log(`menu: ${name}`);
        this.menuSubject.next(name);
      }
    );

    ipcRenderer.on(
      'launch-timing-stats',
      (event: Electron.IpcMessageEvent, { state }: { state: LaunchState }) => {
        console.info(`App ready time: ${state.mainReadyTime}ms`);
        console.info(`Load time: ${state.loadTime}ms`);
        console.info(`Renderer ready time: ${state.rendererReadyTime}ms`);

        this.launchService
          .save(state)
          .pipe(
            map((id: number) => { }),
            catchError(error => {
              return of();
            }),
            take(1)
          )
          .subscribe();
      }
    );
  }

  public sendReady(time: number): void {
    ipcRenderer.send('renderer-ready', time);
  }

  public getAppMenu(): void {
    ipcRenderer.send('get-app-menu');
  }
}
