import { HostListener, Injectable } from '@angular/core';
import { BehaviorSubject, filter } from 'rxjs';
import { Logger } from 'src/app/service/logger.service';
import { NavigationEnd, Router } from '@angular/router';
import { SidebarService } from 'src/app/service/sidebar.service';
import { ConfigService } from 'src/app/service/config.service';
import { Apollo, gql } from 'apollo-angular';
import { AuthService } from 'src/app/service/auth.service';

const logger = new Logger('GuiService');

@Injectable({
  providedIn: 'root',
})
export class GuiService {
  isMobile$ = new BehaviorSubject<boolean>(this.isMobileByWindowWith());
  isTablet$ = new BehaviorSubject<boolean>(this.isTabletByWindowWith());

  loadedGuiSettings$ = new BehaviorSubject<boolean>(false);
  hideGui$ = new BehaviorSubject<boolean>(false);
  theme$ = new BehaviorSubject<string>(this.config.settings.themes[0].name);

  debug$ = new BehaviorSubject<boolean>(false);

  constructor(
    private router: Router,
    private apollo: Apollo,
    private auth: AuthService,
    private sidebarService: SidebarService,
    private config: ConfigService
  ) {
    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe(() => {
        if (this.isMobile$.value) {
          this.sidebarService.hide();
        }
      });

    this.userLogoutSubscription();
  }

  @HostListener('window:resize', ['$event'])
  onResize() {
    this.checkWindowSize();
  }

  private isMobileByWindowWith(): boolean {
    return window.innerWidth <= 600;
  }

  private isTabletByWindowWith(): boolean {
    return window.innerWidth <= 960;
  }

  public checkWindowSize() {
    logger.debug('check window size', {
      mobile: this.isMobileByWindowWith(),
      tablet: this.isTabletByWindowWith(),
      size: window.innerWidth,
    });

    const isMobile = this.isMobileByWindowWith();
    if (isMobile) {
      this.isMobile$.next(true);
      this.isTablet$.next(false);
      return;
    }
    this.isTablet$.next(this.isTabletByWindowWith());
    this.isMobile$.next(false);
  }

  public hexToRGB(hex: string, alpha: number): string {
    const r = parseInt(hex.slice(1, 3), 16),
      g = parseInt(hex.slice(3, 5), 16),
      b = parseInt(hex.slice(5, 7), 16);

    if (alpha) {
      return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
    } else {
      return 'rgb(' + r + ', ' + g + ', ' + b + ')';
    }
  }

  public show() {
    this.hideGui$.next(false);
  }

  public hide() {
    this.hideGui$.next(true);
  }

  private userLogoutSubscription() {
    this.apollo
      .subscribe<{ userLogout: void }>({
        query: gql`
          subscription userLogout {
            userLogout
          }
        `,
      })
      .subscribe(async () => {
        await this.auth.logout();
      });
  }
}
