/*
 * Copyright (C) 2023 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 {ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {AlertController, ToastController} from '@ionic/angular/standalone';
import {TranslateService} from '@ngx-translate/core';
import {SCSettingMeta} from '@openstapps/core';
import {SettingsCache, SettingsProvider} from '../settings.provider';

/**
 * Settings page component
 */
@Component({
  selector: 'stapps-settings-page',
  templateUrl: 'settings-page.html',
  styleUrls: ['settings-page.scss'],
})
export class SettingsPageComponent implements OnInit {
  /**
   * Order of the categories
   */
  categoriesOrder: string[];

  /**
   * Meta information about settings
   */
  meta = SCSettingMeta;

  /**
   * Mapping of Object.keys for Html usage
   */
  objectKeys = Object.keys;

  /**
   * Container to cache settings from provider
   */
  settingsCache: SettingsCache;

  /**
   *
   * @param alertController AlertController
   * @param settingsProvider SettingsProvider
   * @param toastController ToastController
   * @param translateService TranslateService
   * @param changeDetectorRef ChangeDetectorRef
   */
  constructor(
    private readonly alertController: AlertController,
    private readonly settingsProvider: SettingsProvider,
    private readonly toastController: ToastController,
    private readonly translateService: TranslateService,
    private readonly changeDetectorRef: ChangeDetectorRef,
  ) {
    this.settingsCache = {};
  }

  /**
   * Presents a Toast with message for settings successful reset
   */
  private async presentSettingsResetToast() {
    const toast = await this.toastController.create({
      cssClass: 'ion-text-center',
      duration: 2000,
      message: this.translateService.instant('settings.resetToast.message'),
    });

    return toast.present();
  }

  /**
   * Loads cache of settings from SettingProvider
   */
  async loadSettings(): Promise<void> {
    this.settingsCache = await this.settingsProvider.getCache();
    // categoriesOrder triggers updating the View, because it is used in the ngFor loop
    this.categoriesOrder = this.settingsProvider.getCategoriesOrder();
    this.changeDetectorRef.detectChanges();
  }

  /**
   * Component initialize method
   */
  async ngOnInit() {
    await this.loadSettings();
  }

  /**
   * Presents an alert to the user to reset settings to default values
   */
  async presentResetAlert() {
    const cancelText = await this.translateService.get('settings.resetAlert.buttonCancel').toPromise();
    const yesText = await this.translateService.get('settings.resetAlert.buttonYes').toPromise();
    const title = await this.translateService.get('settings.resetAlert.title').toPromise();
    const message = await this.translateService.get('settings.resetAlert.message').toPromise();

    const alert = await this.alertController.create({
      buttons: [
        {
          role: 'cancel',
          text: cancelText,
        },
        {
          handler: async () => {
            await this.resetSettings();
          },
          text: yesText,
        },
      ],
      header: title,
      message: message,
    });
    await alert.present();
  }

  /**
   * Resets all settings to default values
   */
  async resetSettings() {
    await this.settingsProvider.resetDefault();
    await this.loadSettings();
    await this.presentSettingsResetToast();
  }

  /**
   * Shows alert to reset settings
   */
  async showResetAlert() {
    const alert = await this.alertController.create({
      buttons: [
        {
          role: 'cancel',
          text: this.translateService.instant('settings.resetAlert.buttonCancel'),
        },
        {
          handler: async () => {
            await this.resetSettings();
          },
          text: this.translateService.instant('settings.resetAlert.buttonYes'),
        },
      ],
      header: this.translateService.instant('settings.resetAlert.title'),
      message: this.translateService.instant('settings.resetAlert.message'),
    });

    await alert.present();
  }
}
