import { Injectable } from '@angular/core';
import { Platform } from '@angular/cdk/platform';
import { NativeContainerService } from '@external/native-container';
import { BreakpointObserver } from '@angular/cdk/layout';
import { map } from 'rxjs/operators';

const MATCH_TABLET = '(max-width: 1023px)';

const MATCH_DESKTOP_SMALL = '(min-width: 1024px) and (max-width: 1279px)';

const MATCH_DESKTOP = '(min-width: 1280px)';

const MATCH_DESKTOP_LARGE = '(min-width: 1440px)';

const MATCH_DESKTOP_XLARGE = '(min-width: 1920px)';

const MATCH_DESKTOP_XXLARGE = '(min-width: 2736px)';

@Injectable({
  providedIn: 'root',
})
export class EnvironmentService {
  constructor(
    private _platform: Platform,
    private _nativeContainer: NativeContainerService,
    private _breakpointObserver: BreakpointObserver,
  ) {}

  matchTablet(): boolean {
    return this._breakpointObserver.isMatched(MATCH_TABLET);
  }

  matchTablet$ = this._breakpointObserver.observe(MATCH_TABLET).pipe(map((result) => result.matches));

  matchDesktopSmall(): boolean {
    return this._breakpointObserver.isMatched(MATCH_DESKTOP_SMALL);
  }

  matchDesktopSmall$ = this._breakpointObserver.observe(MATCH_DESKTOP_SMALL).pipe(map((result) => result.matches));

  matchDesktop(): boolean {
    return this._breakpointObserver.isMatched(MATCH_DESKTOP);
  }

  matchDesktop$ = this._breakpointObserver.observe(MATCH_DESKTOP).pipe(map((result) => result.matches));

  matchDesktopLarge(): boolean {
    return this._breakpointObserver.isMatched(MATCH_DESKTOP_LARGE);
  }

  matchDesktopLarge$ = this._breakpointObserver.observe(MATCH_DESKTOP_LARGE).pipe(map((result) => result.matches));

  matchDesktopXLarge(): boolean {
    return this._breakpointObserver.isMatched(MATCH_DESKTOP_XLARGE);
  }

  matchDesktopXLarge$ = this._breakpointObserver.observe(MATCH_DESKTOP_XLARGE).pipe(map((result) => result.matches));

  matchDesktopXXLarge(): boolean {
    return this._breakpointObserver.isMatched(MATCH_DESKTOP_XXLARGE);
  }

  matchDesktopXXLarge$ = this._breakpointObserver.observe(MATCH_DESKTOP_XXLARGE).pipe(map((result) => result.matches));

  isMobileDevice(): boolean {
    return this._platform.ANDROID || this._platform.IOS;
  }

  /**
   * @deprecated Use `matchDesktopSmall` or 'matchDesktop' instead.
   */
  isDesktop(): boolean {
    return !this.isTablet();
  }

  /**
   * @deprecated Use `matchTablet` instead.
   */
  isTablet(): boolean {
    return this.isNative() || this.isSafari();
  }

  isNative(): boolean {
    return this._nativeContainer.isNative;
  }

  isSafari(): boolean {
    return this._platform.IOS && this._platform.SAFARI;
  }
}
