/*
 * Copyright (C) 2022 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 {Injectable} from '@angular/core';
import {Client} from '@openstapps/api';
import {SCHebisSearchRequest} from './protocol/request';
import {HebisSearchResponse} from './protocol/response';
import {StorageProvider} from '../storage/storage.provider';
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
import {HttpClient} from '@angular/common/http';
import {DataProvider} from '../data/data.provider';
import {SCHebisSearchRoute} from './protocol/route';
import {SCSearchRequest, SCSearchResponse} from '@openstapps/core';

const HEBIS_PREFIX = 'HEB';

/**
 *  Generated class for the DataProvider provider.
 *
 * See https://angular.io/guide/dependency-injection for more info on providers
 * and Angular DI.
 */
@Injectable({
  providedIn: 'root',
})
export class HebisDataProvider extends DataProvider {
  /**
   * TODO
   */
  storageProvider: StorageProvider;

  httpClient: HttpClient;

  /**
   * Instance of hebis search request route
   */
  private readonly hebisSearchRoute = new SCHebisSearchRoute();

  constructor(
    stAppsWebHttpClient: StAppsWebHttpClient,
    storageProvider: StorageProvider,
    httpClient: HttpClient,
  ) {
    super(stAppsWebHttpClient, storageProvider);
    this.storageProvider = storageProvider;
    this.httpClient = httpClient;
    this.client = new Client(stAppsWebHttpClient, this.backendUrl, this.appVersion);
  }

  override async search(query: SCSearchRequest): Promise<SCSearchResponse> {
    const response = await this.hebisSearch({
      query: query.query ?? '',
      page: query.from,
    });
    console.log(response.pagination);

    return {
      data: response.data,
      facets: [],
      pagination: response.pagination,
      stats: {
        time: Number.NaN,
      },
    };
  }

  /**
   * Send a search request to the backend
   *
   * All results will be returned if no size is set in the request.
   * @param searchRequest Search request
   * @param options Search options
   * @param options.addPrefix Add HeBIS prefix (useful when having only an ID, e.g. when using PAIA)
   */
  async hebisSearch(
    searchRequest: SCHebisSearchRequest,
    options?: {addPrefix: boolean},
  ): Promise<HebisSearchResponse> {
    if (options?.addPrefix) {
      searchRequest.query = [HEBIS_PREFIX, searchRequest.query].join('');
    }

    let page: number | undefined = searchRequest.page;

    if (page === undefined) {
      const preFlightResponse = await this.client.invokeRoute<HebisSearchResponse>(
        this.hebisSearchRoute,
        undefined,
        {
          ...searchRequest,
          page: 0,
        },
      );

      page = preFlightResponse.pagination.total;
    }

    return this.client.invokeRoute<HebisSearchResponse>(this.hebisSearchRoute, undefined, {
      ...searchRequest,
      page,
    });
  }
}
