import { Component, ChangeDetectionStrategy, HostListener, OnInit, AfterContentInit, inject, ChangeDetectorRef } from '@angular/core';
import { handleKeys, selectInputTextOnClick, applyTheme, handleError } from './utils/util';
import { CommonService } from './services/common.service';
import { MessageService } from './services/message.service';
import { BehaviorSubject, catchError, retry, Subject, switchMap } from 'rxjs';
import { ActivatedRoute, RouterOutlet } from '@angular/router';
import { environment } from '../../environments/environment';
import * as util from './utils/util';
import { KENDO_SVGICON } from '@progress/kendo-angular-icons';
import { GlobalBarComponent } from './global-bar/global-bar.component';
import { AsyncPipe } from '@angular/common';
import { HoverClassDirective } from './directives/hover-class-directive';
import { ActiveClassDirective } from './directives/active-class-directive';
import { KENDO_DIALOG } from '@progress/kendo-angular-dialog';
import { AuthService } from './services/auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [KENDO_DIALOG, KENDO_SVGICON, RouterOutlet, GlobalBarComponent, AsyncPipe, HoverClassDirective, ActiveClassDirective]
})
export class AppComponent implements OnInit, AfterContentInit {
  @HostListener('keydown', ['$event']) onKeyDown(e: KeyboardEvent) {
    handleKeys(e);
  }
  @HostListener('mousedown', ['$event']) onMouseDown(e: MouseEvent) {
    selectInputTextOnClick(e);
  }

  commonService = inject(CommonService);
  messageService = inject(MessageService);
  activatedRoute = inject(ActivatedRoute);
  private readonly authService = inject(AuthService);
  private readonly cdr = inject(ChangeDetectorRef);
  icons = util.icons;

  isDev: boolean = !environment.production;
  isRoot: boolean = window.location.hash.toLowerCase() === '#/root';

  //use ngAfterContentInit instead of ngAfterViewInit because ngAfterViewInit causes an "Expression has changed after it was checked" error
  ngAfterContentInit(): void {
    this.activatedRoute.queryParams.subscribe(x => {
      const isTopless = x['topless'] ? true : false;
      this.isToplessSubject.next(isTopless);
      this.cdr.detectChanges(); // Trigger CD as this update might not be detected
    });
  }

  palettePickerOpened = false;
  isToplessSubject = new BehaviorSubject<boolean>(true)
  isTopless$ = this.isToplessSubject.asObservable();
  saveTheme$ = new Subject<string>()

  constructor() {
  }

  ngOnInit(): void {
    applyTheme();
    this.authService.restoreSavedRoute();
  }

  setTheme(themeName: string) {
    localStorage.setItem('theme', themeName);
    applyTheme();
    this.saveTheme$.next(themeName);
    this.palettePickerOpened = false;
  }

  saveThemeResult$ = this.saveTheme$.pipe(
    switchMap(themeName => {
      return this.commonService.saveTheme(themeName);
    }),
    catchError(err => {
      return handleError(err, this.messageService)
    }), retry(10)
  )

  setMouseOver(isMouseOver: boolean, force: boolean = false) {
    this.commonService.setMouseOver(isMouseOver, force);
  }

  setPalettePickerState() {
    this.palettePickerOpened = !this.palettePickerOpened;
    if (this.palettePickerOpened)
      this.setMouseOver(false, true);
  }

}
