import type { Timetable, TimetableResponse, TimetableSearchParams } from '../types/timetables.js';
import { HttpClient } from './http-client.js';

/**
 * Client for interacting with the BODS Timetables API
 * 
 * The Timetables API provides access to bus schedule and route information.
 * Data is updated every 24 hours around 06:00 GMT.
 */
export class TimetablesClient {
  constructor(private httpClient: HttpClient) {}

  /**
   * Search for timetable datasets
   * 
   * @param params - Search parameters to filter timetables
   * @returns Promise resolving to paginated timetable results
   * 
   * @example
   * ```typescript
   * // Find all timetables for a specific operator
   * const timetables = await client.timetables.search({
   *   noc: ['SCMN'],
   *   status: 'published'
   * });
   * 
   * // Search by administrative area
   * const areaTimetables = await client.timetables.search({
   *   adminArea: ['060'], // Cheshire East
   *   limit: 50
   * });
   * 
   * // Search with text query
   * const searchResults = await client.timetables.search({
   *   search: 'Stagecoach',
   *   dqRag: 'green'
   * });
   * ```
   */
  async search(params: TimetableSearchParams = {}): Promise<TimetableResponse> {
    const response = await this.httpClient.get<TimetableResponse>('/api/v1/dataset', params);
    return response.data;
  }

  /**
   * Get a specific timetable dataset by ID
   * 
   * @param datasetId - The unique dataset identifier
   * @returns Promise resolving to the timetable dataset
   * 
   * @example
   * ```typescript
   * const timetable = await client.timetables.getById(86);
   * console.log(timetable.operatorName, timetable.lines);
   * ```
   */
  async getById(datasetId: number): Promise<Timetable> {
    const response = await this.httpClient.get<Timetable>(`/api/v1/dataset/${datasetId}`);
    return response.data;
  }

  /**
   * Get all timetables for a specific operator
   * 
   * @param noc - National Operator Code(s)
   * @param additionalParams - Additional search parameters
   * @returns Promise resolving to paginated timetable results
   * 
   * @example
   * ```typescript
   * const operatorTimetables = await client.timetables.getByOperator(['SCMN', 'SCGH']);
   * ```
   */
  async getByOperator(
    noc: string | string[], 
    additionalParams: Omit<TimetableSearchParams, 'noc'> = {}
  ): Promise<TimetableResponse> {
    return this.search({
      ...additionalParams,
      noc: Array.isArray(noc) ? noc : [noc]
    });
  }

  /**
   * Get timetables for a specific administrative area
   * 
   * @param adminArea - Administrative area code(s)
   * @param additionalParams - Additional search parameters
   * @returns Promise resolving to paginated timetable results
   * 
   * @example
   * ```typescript
   * const areaTimetables = await client.timetables.getByAdminArea('060');
   * ```
   */
  async getByAdminArea(
    adminArea: string | string[], 
    additionalParams: Omit<TimetableSearchParams, 'adminArea'> = {}
  ): Promise<TimetableResponse> {
    return this.search({
      ...additionalParams,
      adminArea: Array.isArray(adminArea) ? adminArea : [adminArea]
    });
  }

  /**
   * Get recently modified timetables
   * 
   * @param since - Date to check for modifications since
   * @param additionalParams - Additional search parameters
   * @returns Promise resolving to paginated timetable results
   * 
   * @example
   * ```typescript
   * const recent = await client.timetables.getRecentlyModified(
   *   new Date('2023-01-01')
   * );
   * ```
   */
  async getRecentlyModified(
    since: Date | string,
    additionalParams: Omit<TimetableSearchParams, 'modifiedDate'> = {}
  ): Promise<TimetableResponse> {
    return this.search({
      ...additionalParams,
      modifiedDate: since
    });
  }

  /**
   * Get high-quality timetables (green data quality rating)
   * 
   * @param additionalParams - Additional search parameters
   * @returns Promise resolving to paginated timetable results
   * 
   * @example
   * ```typescript
   * const qualityTimetables = await client.timetables.getHighQuality({
   *   bodsCompliance: true
   * });
   * ```
   */
  async getHighQuality(
    additionalParams: Omit<TimetableSearchParams, 'dqRag'> = {}
  ): Promise<TimetableResponse> {
    return this.search({
      ...additionalParams,
      dqRag: 'green'
    });
  }
}
