/*
 * 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 {Component, Input} from '@angular/core';
import {AlertController} from '@ionic/angular/standalone';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {SCLanguageCode, SCSetting, SCSettingValue, SCSettingValues} from '@openstapps/core';
import {SettingsProvider} from '../settings.provider';

/**
 * Setting item component
 */
@Component({
  selector: 'stapps-settings-item',
  templateUrl: 'settings-item.html',
  styleUrls: ['settings-item.scss'],
})
export class SettingsItemComponent {
  /**
   * If set the setting will be shown as compact view
   */
  @Input() compactView = false;

  /**
   * Flag for workaround for selected 'select option' not updating translation
   */
  isVisible = true;

  /**
   * The setting to handle
   */
  @Input() setting: SCSetting;

  /**
   *
   * @param alertCtrl AlertController
   * @param translateService TranslateService
   * @param settingsProvider SettingProvider
   */
  constructor(
    private readonly alertCtrl: AlertController,
    private readonly translateService: TranslateService,
    private readonly settingsProvider: SettingsProvider,
  ) {
    translateService.onLangChange.subscribe((_event: LangChangeEvent) => {
      this.isVisible = false;
      // TODO: Issue #53 check workaround for selected 'select option' not updating translation
      setTimeout(() => (this.isVisible = true));
    });
  }

  /**
   * Shows alert with given title and message and a 'ok' button
   * @param title Title of the alert
   * @param message Message of the alert
   */
  async presentAlert(title: string, message: string | null) {
    const alert = await this.alertCtrl.create({
      buttons: ['OK'],
      header: title,
      message: message ?? undefined,
    });
    await alert.present();
  }

  /**
   * Handles value changes of the setting
   */
  async settingChanged(): Promise<void> {
    if (
      this.setting.value !== undefined &&
      SettingsProvider.validateValue(this.setting, this.setting.value)
    ) {
      // handle general settings, with special actions
      switch (this.setting.name) {
        case 'language': {
          this.translateService.use(this.setting.value as SCLanguageCode);
          break;
        }
        default:
      }
      await this.settingsProvider.setSettingValue(
        this.setting.categories[0],
        this.setting.name,
        this.setting.value,
      );
    } else {
      // reset setting
      this.setting.value = (await this.settingsProvider.getValue(
        this.setting.categories[0],
        this.setting.name,
      )) as SCSettingValue | SCSettingValues;
    }
  }

  /**
   * Mapping of typeOf for Html usage
   */
  // eslint-disable-next-line class-methods-use-this
  typeOf(value: unknown) {
    return typeof value;
  }
}
