/*
 * Copyright (C) 2018-2021 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {AfterContentInit, Component, NgZone} from '@angular/core';
import {Router} from '@angular/router';
import {App, URLOpenListenerEvent} from '@capacitor/app';
import {SplashScreen} from '@capacitor/splash-screen';
import {Platform, ToastController} from '@ionic/angular';
import {NGXLogger} from 'ngx-logger';
import {ConfigProvider} from './modules/config/config.provider';
import {SettingsProvider} from './modules/settings/settings.provider';
import {PAIAAuthService} from './modules/auth/paia/paia-auth.service';
import {DefaultAuthService} from './modules/auth/default-auth.service';
import {environment} from '../environments/environment';
import {AuthHelperService} from './modules/auth/auth-helper.service';
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';

/**
 * TODO
 */
@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
})
export class AppComponent implements AfterContentInit {
  /**
   * TODO
   */
  pages: Array<{
    /**
     * TODO
     */
    component: unknown;
    /**
     * TODO
     */
    title: string;
  }>;

  /**
   *
   * @param platform TODO
   * @param settingsProvider TODO
   * @param configProvider TODO
   * @param logger An angular logger
   * @param router The angular router
   * @param zone The angular zone
   * @param defaultAuth Auth Service
   * @param paiaAuth Auth Service
   * @param authHelperService Helper service for OAuth providers
   * @param toastController Toast controller
   * @param scheduleSync TODO
   */
  constructor(
    private readonly platform: Platform,
    private readonly settingsProvider: SettingsProvider,
    private readonly configProvider: ConfigProvider,
    private readonly logger: NGXLogger,
    private readonly router: Router,
    private readonly zone: NgZone,
    private readonly defaultAuth: DefaultAuthService,
    private readonly paiaAuth: PAIAAuthService,
    private readonly authHelperService: AuthHelperService,
    private readonly toastController: ToastController,
    private readonly scheduleSync: ScheduleSyncService,
  ) {
    void this.initializeApp();
  }

  ngAfterContentInit() {
    void this.scheduleSync.enable();
  }

  /**
   * TODO
   */
  async initializeApp() {
    App.addListener('appUrlOpen', (event: URLOpenListenerEvent) => {
      this.zone.run(() => {
        const slug = event.url.split(environment.appDomain).pop();
        if (slug) {
          this.router.navigateByUrl(slug);
        }
        // If no match, do nothing - let regular routing
        // logic take over
      });
    });
    this.platform.ready().then(async () => {
      await this.authInit();
      await this.defaultAuth.init();
      await this.paiaAuth.init();
      await SplashScreen.hide();

      // initialise the configProvider
      try {
        await this.configProvider.init();
      } catch (error) {
        if (
          typeof error.name !== 'undefined' &&
          error.name === 'ConfigInitError'
        ) {
          // TODO: Issue #43 handle initialisation error and inform user
        }
        this.logger.error(error);
      }

      // set order of categories in settings
      this.settingsProvider.setCategoriesOrder([
        'profile',
        'privacy',
        'credentials',
        'others',
      ]);
    });
  }

  private async authInit() {
    await this.defaultAuth.init();
    await this.paiaAuth.init();
    this.defaultAuth.events$.subscribe(action =>
      this.showMessage(
        this.authHelperService.getAuthMessage('default', action),
      ),
    );
    this.paiaAuth.events$.subscribe(action =>
      this.showMessage(this.authHelperService.getAuthMessage('paia', action)),
    );
  }

  private async showMessage(message?: string) {
    if (typeof message === 'undefined') {
      return;
    }
    const toast = await this.toastController.create({
      message: message,
      duration: 2000,
    });
    await toast.present();
  }
}
