import { Component } from '@angular/core';
import { Router } from '@angular/router';

import { Store } from '@ngrx/store';

import { StoreService } from './core/services/store/store.service';
import { AuthService } from './core/services/auth/auth.service';

import { Toast, ToastStore } from './core/interfaces/store/toast.interface';
import { initialState as toastInitialState } from './core/stores/toast/toast.store';
import { tap } from 'rxjs';
import { ToastDispatchers } from './core/stores/index.dispatchers';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  isOffline = !navigator.onLine;

  toastState = { ...toastInitialState };

  constructor(
    private authService: AuthService,
    private storeService: StoreService,
    private router: Router,
    private store: Store<{ toast: ToastStore }>,
    private toastDispatchers: ToastDispatchers,
  ) {}

  ngOnInit() {
    this.setApplicationData();

    this.preventDefaultContextMenu();
    this.setConnectionStatusListener();

    this.setToastState();
  }

  preventDefaultContextMenu() {
    window.addEventListener('contextmenu', (ev) => ev.preventDefault());
  }

  setConnectionStatusListener() {
    window.addEventListener('online', () => {
      this.isOffline = false;
    });

    window.addEventListener('offline', () => {
      this.isOffline = true;
    });
  }

  autoCloseToast(toast: Toast) {
    if (toast.isVisible && toast.shouldHideAutomatically) {
      setTimeout(() => this.toastDispatchers.resetToasts(), toast.delay);
    }
  }

  setToastState() {
    this.store
      .select('toast')
      .pipe(
        tap({
          next: (change) => {
            const toasts = Object.values(change);
            toasts.forEach((t) => this.autoCloseToast(t));
          },
        }),
      )
      .subscribe({
        next: (toastState) => {
          this.toastState = {
            ...structuredClone(toastState),
          };
        },
      });
  }

  async setApplicationData() {
    const token = this.authService.getAuthorizationToken();
    if (!token) return;

    try {
      this.storeService.setStore();
    } catch (err) {
      this.router.navigate(['/app/auth/login']);
    }
  }
}
