import { Observable, Subject } from 'rxjs';

import {
  NativeService,
  WindowState,
  NotificationRequest,
  WindowIdle
} from '@ucap-webmessenger/native';
import { HttpClient } from '@angular/common/http';
import { map, share } from 'rxjs/operators';
import { TranslateLoader } from '@ngx-translate/core';
import { TranslateLoaderService } from '../translate/browser-loader';
import { NotificationService } from '../notification/notification.service';
import { Injectable } from '@angular/core';
import { FileUtil, StatusCode } from '@ucap-webmessenger/core';

@Injectable({
  providedIn: 'root'
})
export class BrowserNativeService extends NativeService {
  private notificationService: NotificationService;

  private chatOpenRoomSubject: Subject<string> | null = null;
  private chatOpenRoom$: Observable<string> | null = null;

  postAppInit(): void {
    this.notificationService.requestPermission();
  }

  logout(): Observable<void> {
    return new Observable<void>(subscriber => {
      try {
      } catch (error) {
        subscriber.error(error);
      } finally {
        subscriber.complete();
      }
    });
  }

  changeStatus(): Observable<StatusCode> {
    return new Observable<StatusCode>(subscriber => {
      try {
      } catch (error) {
        subscriber.error(error);
      } finally {
        subscriber.complete();
      }
    });
  }

  showSetting(): Observable<void> {
    return new Observable<void>(subscriber => {
      try {
      } catch (error) {
        subscriber.error(error);
      } finally {
        subscriber.complete();
      }
    });
  }

  notify(noti: NotificationRequest): void {
    this.notificationService.notify(noti, () => {
      window.focus();
      this.chatOpenRoomSubject.next(noti.roomSeq);
    });
  }
  closeAllNotify(): void {}

  checkForUpdates(): Promise<boolean> {
    return new Promise<boolean>((resolve, reject) => {
      resolve(false);
    });
  }

  showImageViewer(): void {}

  readFile(path: string): Promise<Buffer> {
    return new Promise<Buffer>((resolve, reject) => {
      resolve(null);
    });
  }

  saveFile(
    buffer: Buffer,
    fileName: string,
    mimeType: string,
    path?: string
  ): Promise<string> {
    return new Promise<string>((resolve, reject) => {
      try {
        FileUtil.save(buffer, fileName, mimeType).then(fn => {
          resolve(fn);
        });
      } catch (error) {
        reject(error);
      }
    });
  }

  windowStateChanged(): Observable<WindowState> {
    return new Observable<WindowState>(subscriber => {
      try {
        subscriber.next(WindowState.Normal);
      } catch (error) {
        subscriber.error(error);
      } finally {
        subscriber.complete();
      }
    });
  }

  windowClose(): void {}

  windowMinimize(): void {}

  windowMaximize(): void {}

  idleStateChanged(): Observable<WindowIdle> {
    return new Observable<WindowIdle>(subscriber => {
      try {
      } catch (error) {
        subscriber.error(error);
      } finally {
        subscriber.complete();
      }
    });
  }

  chatOpenRoom(): Observable<string> {
    if (!this.chatOpenRoomSubject) {
      this.chatOpenRoomSubject = new Subject<WindowIdle>();
      this.chatOpenRoom$ = this.chatOpenRoomSubject
        .asObservable()
        .pipe(share());
    }

    return this.chatOpenRoom$;
  }

  getTranslateLoader(prefix?: string, suffix?: string): TranslateLoader {
    return new TranslateLoaderService(this, prefix, suffix);
  }

  openDefaultBrowser(url: string): void {
    open(url);
  }

  constructor(private httpClient: HttpClient) {
    super();
    this.notificationService = new NotificationService();
  }
}
