import { Injectable } from '@angular/core';
import { Diagnostic } from '@ionic-native/diagnostic/ngx';
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
import { Observable } from 'rxjs';
import { SubjectSubscriber } from 'rxjs/internal/Subject';
import { TranslatorService } from '../translator/translator.service';
import { promise } from 'protractor';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { OpenNativeSettings } from '@ionic-native/open-native-settings/ngx';


@Injectable({
  providedIn: 'root'
})
export class DevicePermissionsService {

  constructor(
    public diagnostic: Diagnostic,
    public cs: CommonService,
    public nativeStorage: NativeStorage,
    public ts: TranslatorService,
    public nativeSettings: OpenNativeSettings) { }
  public static GRANTED = 'GRANTED';
  public static DENIED_ALWAYS = 'DENIED_ALWAYS';

  public static CAMERA_MIC = 'camera_mic_permission';
  public static LOCATION = 'location_permission';


  public static APP_SETTINGS = 'application_details';

  public onSucess;
  public onerror;

  public requestCameraPermission(): Observable<boolean> {

    return Observable.create(observer => {
      this.requestCamera(observer);
    });
  }

  private requestCamera(observer: any) {
    this.hasCameraPermission().then((isAvailable) => {
      if (isAvailable) {
       // this.requestMicophonePermission(observer);
       this.observerDone(observer, true);
      } else {
        this.diagnostic.requestCameraAuthorization(true).then((value) => {
          // tslint:disable-next-line: triple-equals
          if (value == DevicePermissionsService.GRANTED) {
            // this.requestMicophonePermission(observer);
            this.observerDone(observer, true);
          // tslint:disable-next-line: triple-equals
          } else if (value == DevicePermissionsService.DENIED_ALWAYS) {
           // this.setAlwaysDenied(DevicePermissionsService.CAMERA_MIC, true);
            this.observerDone(observer, false);
          } else {
            this.observerDone(observer, false);
          }
        });
      }
    }, () => {
      this.observerDone(observer, false);
    });
  }


  private cameraError(observer) {
    this.cs.presentConfirmDialog('camera permission required', () => {
      this.requestCamera(observer);
    }, () => {
      this.observerDone(observer, false);
    });
  }


  private requestMicophonePermission(observer: any) {
    this.diagnostic.isMicrophoneAuthorized().then((isAvailable) => {

      if (isAvailable) {
        this.observerDone(observer, true);
      } else {
        this.diagnostic.requestMicrophoneAuthorization().then((value) => {
          // tslint:disable-next-line: triple-equals
          if (value == DevicePermissionsService.GRANTED) {
            this.observerDone(observer, true);
          // tslint:disable-next-line: triple-equals
          } else if (value == DevicePermissionsService.DENIED_ALWAYS) {
            this.setAlwaysDenied(DevicePermissionsService.CAMERA_MIC, true);
            this.observerDone(observer, false);
          } else {
            this.observerDone(observer, false);
          }
        });
      }

    }, () => {
      this.observerDone(observer, false);
    });
    // // Checks microphone permissions
  }

  private micError(observer) {
    this.cs.presentConfirmDialog('Michrophone permission required', () => {
      this.requestMicophonePermission(observer);
    }, () => {
      this.observerDone(observer, false);
    });
  }

  private observerDone(observer: any, success: boolean) {
    observer.next(success);
    observer.complete();
  }

  public async  hasCameraPermission(): Promise<boolean> {
    return this.diagnostic.isCameraAuthorized(true);
  }

  public async  hasCameraAndMicPermissions(): Promise<boolean> {
    const camera = await this.hasCameraPermission();
    // let mic = await this.diagnostic.isMicrophoneAuthorized();
    if (camera) {
     // await this.setAlwaysDenied(DevicePermissionsService.CAMERA_MIC, false);
      return true;
    } else {
      return false;
    }
  }

  private permissionRequestDialog(message: string): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.cs.confirmAlertDialogPrimarySecondary(() => {
        resolve(true);
      }, this.ts.trPK('general', 'accept'),
        () => {
          resolve(false);
        }, this.ts.trPK('general', 'not-now'), this.ts.trPK('general', 'confirm'), message
      );
    });
  }

  private permissionSettingsDialog(message) {
    return new Promise((resolve, reject) => {
      this.cs.confirmAlertDialogPrimarySecondary(() => {
        resolve(true);
      }, this.ts.trPK('general', 'settings'),
        () => {
          resolve(false);
        }, this.ts.trPK('general', 'not-now'), this.ts.trPK('general', 'confirm'), message
      );
    });
  }

  public async openApplicationSettings() {
    // return new Promise((resolver, reject) => {
    //   this.nativeSettings.open(DevicePermissionsService.APP_SETTINGS).then(result => {
    //     setTimeout(() => {
    //       this.cs.presentConfirmDialog(this.ts.trPK('permissions', 'check-updates'),
    //         () => resolver(true), () => resolver(false)
    //       );
    //     }, 1500);

    //   });
    // });
  }

  private async isPermissionAlwaysDenied(permissionKey: string) {
    // return new Promise((resolver, rejector) => {
    //   this.nativeStorage.getItem(permissionKey).then(denied => {
    //     resolver(denied != null && denied == true);
    //   }, () => {
    //     resolver(false);
    //   });
    // });

  }

  private async resetAlwaysDenied(permissionKey: string) {
    return new Promise((resolver, rejector) => {
      this.nativeStorage.setItem(permissionKey, false).then(done => {
        resolver(done);
      }, () => {
        resolver(false);
      });
    });
  }


  private async setAlwaysDenied(permissionKey: string, dendied: boolean) {
    // let result = await this.nativeStorage.setItem(permissionKey, dendied);
    // return result;
  }

  public async openCameraAndMicSettings2() {
    // return new Promise((resolver, reject) => {
    //   this.nativeSettings.open('application_details').then(result => {
    //     setTimeout(() => {
    //       this.cs.presentConfirmDialog(this.ts.trPK('permissions', 'check-updates'), () => {
    //         this.hasCameraAndMicPermissions().then(
    //           granted => resolver(granted), () => resolver(false));
    //       });
    //     }, 1000);

    //   });
    // });
  }


  public async requestCameraAutherization() {
    if (await this.hasCameraAndMicPermissions()) {
      return true;
    } else {
      const message = this.ts.trPK('permissions', 'camera');
      // if (await this.isPermissionAlwaysDenied(DevicePermissionsService.CAMERA_MIC)) {
      //   if (await this.permissionSettingsDialog(message)) {
      //     return this.openCameraAndMicSettings();
      //   }
      // } else {
      if (await this.permissionRequestDialog(message)) {
          return this.requestCameraPermission().toPromise();
        }
      // }
      return false;
    }

  }

  /* geolocation permission */

  public async requestLocationAutherization() {
    if ( await this.isLocationEnabled()) {
      if (await this.hasLocationPermissions()) {
        return true;
      } else {
        const message = this.ts.trPK('permissions', 'location');
        // if (await this.isPermissionAlwaysDenied(DevicePermissionsService.LOCATION)) {
        //   if (await this.permissionSettingsDialog(message)) {
        //     return this.openLocationSettings();
        //   }
        // } else {
        if (await this.permissionRequestDialog(message)) {
            return this.requestLocationPermission();
          }
        // }
        return false;
      }
    } else {
      return false;
    }
  }

  private async isLocationEnabled() {
    const isAvailable = await this.diagnostic.isLocationEnabled();
    if (!isAvailable) {
      this.cs.presentAlert(this.ts.trPK('permissions', 'enable-location'), () => {
      });
    }
    return isAvailable;
  }

  public async  hasLocationPermissions(): Promise<boolean> {
    const location = await this.diagnostic.isLocationAvailable();
    if (location) {
      await this.setAlwaysDenied(DevicePermissionsService.LOCATION, false);
      return true;
    } else {
      return false;
    }
  }


  public async openCameraAndMicSettings() {
    // let update = await this.openApplicationSettings();
    // return update ? this.hasCameraAndMicPermissions() : false;
  }

  public async openLocationSettings() {
    // let update = await this.openApplicationSettings();
    // return update ? this.hasLocationPermissions() : false;
  }


  private async requestLocationPermission() {
    const hasPermissions = await this.hasLocationPermissions();
    if (!hasPermissions) {

      const value = await this.diagnostic.requestLocationAuthorization();
      // tslint:disable-next-line: triple-equals
      if (value == DevicePermissionsService.GRANTED) {
        return true;
      // tslint:disable-next-line: triple-equals
      } else if (value == DevicePermissionsService.DENIED_ALWAYS) {
        this.setAlwaysDenied(DevicePermissionsService.LOCATION, true);
      }
    }
    return false;
  }

}


