import {
  AfterViewInit,
  Component,
  Inject,
  OnDestroy,
  OnInit,
  ViewChild,
  ViewContainerRef,
  DOCUMENT,
} from '@angular/core';

import { TranslateService } from '@ngx-translate/core';
import {
  BackendConfigurationService,
  LabelsService,
  SDKService,
  STFSplashScreenService,
  STFUtils,
  UserService,
} from '@flaps/core';
import { Subject } from 'rxjs';
import { TranslateService as PaTranslateService } from '@guillotinaweb/pastanaga-angular';
import { takeUntil } from 'rxjs/operators';
import { SisModalService } from '@nuclia/sistema';
import { FeaturesModalComponent } from '@flaps/common';

// Warning: this key name is declared in both dashboard app.component and in @nuclia/sync
// to avoid making a dependency
const PENDING_NEW_CONNECTOR_KEY = 'PENDING_NEW_CONNECTOR';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  standalone: false,
})
export class AppComponent implements AfterViewInit, OnInit, OnDestroy {
  @ViewChild('toastsContainer', { read: ViewContainerRef, static: true }) toastsContainer?: ViewContainerRef;

  private unsubscribeAll: Subject<void>;

  version: string | undefined;

  constructor(
    private user: UserService,
    private splashScreenService: STFSplashScreenService,
    private config: BackendConfigurationService,
    private ngxTranslate: TranslateService,
    private sdk: SDKService,
    private paTranslate: PaTranslateService,
    private labelService: LabelsService,
    private modalService: SisModalService,
    @Inject(DOCUMENT) private document: any,
  ) {
    this.unsubscribeAll = new Subject();

    this.initTranslate(undefined);
    this.user.userPrefs.subscribe((prefs) => {
      this.initTranslate(prefs?.language?.toLowerCase());
    });
    this.sdk.nuclia.auth.hasLoggedOut().subscribe(() => {
      this.sdk.nuclia.auth.redirectToOAuth();
      this.sdk.cleanAccount();
    });

    this.redirectToSyncCreation();
    if (this.config.useRemoteLogin()) {
      this.remoteLogin();
    }
    this.labelService.initLabelSets();
  }

  ngOnInit() {
    if (this.config.getVersion()) {
      this.version = this.config.getVersion();
    }
    this.preventDragAndDropOnWindow();
    this.listenFeatureFlagCode();
  }

  ngOnDestroy(): void {
    this.unsubscribeAll.next();
    this.unsubscribeAll.complete();
    this.cleanUpEventListener();
  }

  ngAfterViewInit() {
    this.splashScreenService.hide();
  }

  initTranslate(userLocale?: string) {
    this.ngxTranslate.setDefaultLang('en');
    const browserLang = this.ngxTranslate.getBrowserLang();

    if (userLocale && userLocale !== '') {
      this.ngxTranslate.use(userLocale);
    } else if (browserLang && STFUtils.supportedLanguages().indexOf(browserLang) > -1) {
      this.ngxTranslate.use(browserLang);
    } else {
      this.ngxTranslate.use('en');
    }

    this.ngxTranslate.onLangChange
      .pipe(takeUntil(this.unsubscribeAll))
      .subscribe((event) => this.paTranslate.initTranslationsAndUse(event.lang, event.translations));
  }

  private preventDefault(e: DragEvent) {
    e.preventDefault();
  }

  private preventDragAndDropOnWindow() {
    window.addEventListener('dragover', this.preventDefault, false);
    window.addEventListener('drop', this.preventDefault, false);
  }

  private cleanUpEventListener() {
    window.removeEventListener('dragover', this.preventDefault);
    window.removeEventListener('drop', this.preventDefault);
  }

  private remoteLogin() {
    const params = location.search;
    if (params.includes('access_token')) {
      const querystring = new URLSearchParams(params.split('?')[1]);
      const access_token = querystring.get('access_token');
      if (access_token) {
        this.sdk.nuclia.auth.authenticate({
          access_token,
          refresh_token: querystring.get('refresh_token') || '',
        });
      }
    }
  }

  private redirectToSyncCreation() {
    const params = location.search;
    if (params.includes('external_connection_id')) {
      const querystring = new URLSearchParams(params.split('?')[1]);
      const external_connection_id = querystring.get('external_connection_id');
      const redirect = JSON.parse(localStorage.getItem(PENDING_NEW_CONNECTOR_KEY) || '{}')['redirect'];
      if (external_connection_id && redirect) {
        location.href = `${redirect}/${external_connection_id}`;
      } else {
        // DEV PURPOSE
        // when working on localhost, the oauth flow redirect to stage, we need to know external_connection_id
        // so we can pass it manuallly to localhost
        console.info('external_connection_id', external_connection_id);
      }
    }
  }

  listenFeatureFlagCode() {
    const activationKeyCodes = [
      'ArrowUp',
      'ArrowUp',
      'ArrowDown',
      'ArrowDown',
      'ArrowLeft',
      'ArrowRight',
      'ArrowLeft',
      'ArrowRight',
      'KeyB',
      'KeyA',
    ];
    let userKeys: string[] = [];
    this.document.addEventListener('keyup', (event: KeyboardEvent) => {
      if ((event.target as HTMLElement).tagName === 'INPUT') return;
      userKeys = [...userKeys, event.code].slice(-activationKeyCodes.length);
      if (JSON.stringify(activationKeyCodes) === JSON.stringify(userKeys)) {
        this.modalService.openModal(FeaturesModalComponent);
      }
    });
  }
}
