/*
 * Copyright (C) 2020-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 {Component, OnInit} from '@angular/core';
import {IonRefresher} from '@ionic/angular';
import {
  SCMessage,
  SCSearchFilter,
  SCSearchValueFilter,
  SCSetting,
} from '@openstapps/core';
import {SettingsProvider} from '../../settings/settings.provider';
import {
  newsFilterSettingsCategory,
  newsFilterSettingsFieldsMapping,
  NewsFilterSettingsNames,
} from '../news-filter-settings';
import {NewsProvider} from '../news.provider';
/**
 * News page component
 */
@Component({
  selector: 'stapps-news-page',
  templateUrl: 'news-page.html',
})
export class NewsPageComponent implements OnInit {
  /**
   * Thing counter to start query the next page from
   */
  from = 0;

  /**
   * News (messages) to show
   */
  news: SCMessage[] = [];

  /**
   * Page size of queries
   */
  pageSize = 10;

  /**
   * Relevant settings
   */
  settings: SCSetting[];

  /**
   * Active filters
   */
  filters: SCSearchFilter[];

  constructor(
    private newsProvider: NewsProvider,
    private settingsProvider: SettingsProvider,
  ) {}

  /**
   * Fetch news from the backend
   */
  async fetchNews() {
    this.from = 0;
    this.news = await this.newsProvider.getList(this.pageSize, this.from, [
      ...this.filters,
    ]);
  }

  /**
   * Loads more news
   *
   * @param infiniteScrollElement Infinite scroll element
   */
  async loadMore(
    infiniteScrollElement: HTMLIonInfiniteScrollElement,
  ): Promise<void> {
    this.from += this.pageSize;
    this.news = [
      ...this.news,
      ...(await this.newsProvider.getList(this.pageSize, this.from, [
        ...this.filters,
      ])),
    ];
    await infiniteScrollElement.complete();
  }

  /**
   * Initialize the local variables on component initialization
   */
  async ngOnInit() {
    // Helper method to provide the relevant settings
    const getNewsSettings = async (settingNames: NewsFilterSettingsNames[]) => {
      const settings = [];
      for (const settingName of settingNames) {
        settings.push(
          await this.settingsProvider.getSetting(
            newsFilterSettingsCategory,
            settingName,
          ),
        );
      }
      return settings;
    };

    this.settings = await getNewsSettings(
      Object.keys(newsFilterSettingsFieldsMapping) as NewsFilterSettingsNames[],
    );
  }

  /**
   * Updates the shown list
   *
   * @param refresher Refresher component that triggers the update
   */
  async refresh(refresher: IonRefresher) {
    try {
      await this.fetchNews();
    } catch {
      this.news = [];
    } finally {
      await refresher.complete();
    }
  }

  /**
   * Executed when filters have been changed
   *
   * @param filters Current filters to be used
   */
  toggleFilter(filters: SCSearchValueFilter[]) {
    this.filters = filters;
    void this.fetchNews();
  }
}
