/**
 * @fileoverview Vocabulary sub-client for European Parliament API
 *
 * Handles EP controlled-vocabularies endpoints (list and single-item lookup).
 *
 * @module clients/ep/vocabularyClient
 */

import type { PaginatedResponse } from '../../types/europeanParliament.js';
import {
  BaseEPClient,
  APIError,
  type EPClientConfig,
  type EPSharedResources,
  type JSONLDResponse,
} from './baseClient.js';

/**
 * Sub-client for EP controlled-vocabularies endpoints.
 *
 * @extends BaseEPClient
 * @public
 */
export class VocabularyClient extends BaseEPClient {
  constructor(config: EPClientConfig = {}, shared?: EPSharedResources) {
    super(config, shared);
  }

  /**
   * Returns EP controlled vocabularies.
   * **EP API Endpoint:** `GET /controlled-vocabularies`
   *
   * @param params - limit, offset
   * @returns Raw API response with vocabulary items
   */
  async getControlledVocabularies(params: {
    limit?: number;
    offset?: number;
    abortSignal?: AbortSignal;
  } = {}): Promise<PaginatedResponse<Record<string, unknown>>> {
    const limit = params.limit ?? 50;
    const offset = params.offset ?? 0;

    const response = await this.get<JSONLDResponse>('controlled-vocabularies', {
      format: 'application/ld+json',
      offset,
      limit,
    }, undefined, params.abortSignal);

    const items = Array.isArray(response.data) ? response.data : [];
    const hasMore = items.length === limit;
    return { data: items, total: items.length + offset + (hasMore ? 1 : 0), limit, offset, hasMore };
  }

  /**
   * Retrieves recently updated controlled vocabularies via the feed endpoint.
   * **EP API Endpoint:** `GET /controlled-vocabularies/feed`
   *
   * Fixed-window feed — no `timeframe` parameter per OpenAPI spec.
   * Returns HTTP 204 No Content when no updates exist (handled by baseClient).
   */
  async getControlledVocabulariesFeed(options: { abortSignal?: AbortSignal } = {}): Promise<JSONLDResponse> {
    return this.get<JSONLDResponse>('controlled-vocabularies/feed', {
      format: 'application/ld+json',
    }, undefined, options.abortSignal);
  }

  /**
   * Returns a single EP Controlled Vocabulary by ID.
   * **EP API Endpoint:** `GET /controlled-vocabularies/{voc-id}`
   *
   * @param vocId - Vocabulary identifier
   * @returns Single vocabulary entry
   */
  async getControlledVocabularyById(
    vocId: string,
    options: { abortSignal?: AbortSignal } = {},
  ): Promise<Record<string, unknown>> {
    if (vocId.trim() === '') {
      throw new APIError('Vocabulary ID is required', 400);
    }
    const response = await this.get<Record<string, unknown>>(
      `controlled-vocabularies/${vocId}`,
      { format: 'application/ld+json' },
      undefined,
      options.abortSignal,
    );
    return response;
  }
}
