/*
 * 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, OnInit} from '@angular/core';
import {AlertController, AnimationController, ModalController} from '@ionic/angular/standalone';
import {ActivatedRoute, Router} from '@angular/router';
import {NGXLogger} from 'ngx-logger';
import {debounceTime, distinctUntilChanged, startWith, take} from 'rxjs/operators';
import {combineLatest} from 'rxjs';
import {SCThingType} from '@openstapps/core';
import {FavoritesService} from './favorites.service';
import {DataRoutingService} from '../data/data-routing.service';
import {ContextMenuService} from '../menu/context/context-menu.service';
import {SearchPageComponent} from '../data/list/search-page.component';
import {DataProvider} from '../data/data.provider';
import {SettingsProvider} from '../settings/settings.provider';
import {PositionService} from '../map/position.service';
import {ConfigProvider} from '../config/config.provider';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

/**
 * The page for showing favorites
 */
@Component({
  templateUrl: '../data/list/search-page.html',
  providers: [ContextMenuService],
  styleUrls: ['../data/list/search-page.scss'],
})
export class FavoritesPageComponent extends SearchPageComponent implements OnInit {
  title = 'favorites.page.TITLE';

  showNavigation = false;

  constructor(
    alertController: AlertController,
    dataProvider: DataProvider,
    contextMenuService: ContextMenuService,
    settingsProvider: SettingsProvider,
    logger: NGXLogger,
    dataRoutingService: DataRoutingService,
    router: Router,
    route: ActivatedRoute,
    positionService: PositionService,
    private favoritesService: FavoritesService,
    configProvider: ConfigProvider,
    animationController: AnimationController,
    modalController: ModalController,
  ) {
    super(
      alertController,
      dataProvider,
      contextMenuService,
      settingsProvider,
      logger,
      dataRoutingService,
      router,
      route,
      positionService,
      configProvider,
      animationController,
      modalController,
    );
  }

  ngOnInit() {
    super.ngOnInit(false);

    // Recreate subscriptions to handle different routing
    combineLatest([
      this.queryTextChanged.pipe(
        debounceTime(this.searchQueryDueTime),
        distinctUntilChanged(),
        startWith(this.queryText),
      ),
      this.contextMenuService.filterQueryChanged$.pipe(startWith(this.filterQuery)),
      this.contextMenuService.sortQueryChanged$.pipe(startWith(this.sortQuery)),
      this.favoritesService.favoritesChanged$,
    ])
      .pipe(takeUntilDestroyed(this.destroy$))
      .subscribe(async query => {
        this.queryText = query[0];
        this.filterQuery = query[1];
        this.sortQuery = query[2];
        this.from = 0;
        if (this.filterQuery !== undefined || this.queryText?.length > 0 || this.showDefaultData) {
          await this.fetchAndUpdateItems();
          this.queryChanged.next();
        }
      });
    this.settingsProvider.settingsActionChanged$
      .pipe(takeUntilDestroyed(this.destroy$))
      .subscribe(({type, payload}) => {
        if (type === 'stapps.settings.changed') {
          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
          const {category, name, value} = payload!;
          this.logger.log(`received event "settings.changed" with category:
            ${category}, name: ${name}, value: ${JSON.stringify(value)}`);
        }
      });
    this.dataRoutingService
      .itemSelectListener()
      .pipe(takeUntilDestroyed(this.destroy$))
      .subscribe(item => {
        if (this.itemRouting) {
          if ([SCThingType.Book, SCThingType.Periodical, SCThingType.Article].includes(item.type)) {
            void this.router.navigate(
              [
                'hebis-detail',
                (item.origin && 'originalId' in item.origin && item.origin['originalId']) || '',
              ],
              {state: {item}},
            );
          } else {
            void this.router.navigate(['data-detail', item.uid], {state: {item}});
          }
        }
      });
  }

  /**
   * Fetches/updates the favorites (search page component's method override)
   */
  async fetchAndUpdateItems() {
    this.favoritesService
      .search(this.queryText, this.filterQuery, this.sortQuery)
      .pipe(take(1))
      .subscribe(result => {
        this.items = (async () => result.data)();
        this.updateContextFilter(result.facets);
      });
  }

  initialize() {
    this.showDefaultData = true;
  }
}
