import { BaseServiceParams } from "..";
import { SyncTranscriber } from "./sync";
import { SyncTranscriptError } from "../utils/errors";
import { LemurService } from "./lemur";
import {
  RealtimeTranscriber,
  RealtimeTranscriberFactory,
  RealtimeService,
  RealtimeServiceFactory,
} from "./realtime";
import { TranscriptService } from "./transcripts";
import { FileService } from "./files";
import {
  StreamingTranscriber,
  StreamingTranscriberFactory,
  DualChannelCapture,
  EnergyVad,
  LinearResampler,
  VadTimeline,
  attributeTurn,
  attributeWord,
  rollUpTurnChannel,
  float32ToPcm16,
} from "./streaming";

const defaultBaseUrl = "https://api.assemblyai.com";
const defaultStreamingUrl = "https://streaming.assemblyai.com";
const defaultSyncUrl = "https://sync.assemblyai.com";

class AssemblyAI {
  /**
   * The files service.
   */
  public files: FileService;

  /**
   * The transcripts service.
   */
  public transcripts: TranscriptService;

  /**
   * The LeMUR service.
   */
  public lemur: LemurService;

  /**
   * The realtime service.
   */
  public realtime: RealtimeTranscriberFactory;

  /**
   * The streaming service.
   */
  public streaming: StreamingTranscriberFactory;

  /**
   * The synchronous transcription service.
   */
  public sync: SyncTranscriber;

  /**
   * Create a new AssemblyAI client.
   * @param params - The parameters for the service, including the API key and base URL, if any.
   */
  constructor(params: BaseServiceParams) {
    params.baseUrl = params.baseUrl || defaultBaseUrl;
    if (params.baseUrl && params.baseUrl.endsWith("/")) {
      params.baseUrl = params.baseUrl.slice(0, -1);
    }

    this.files = new FileService(params);
    this.transcripts = new TranscriptService(params, this.files);
    this.lemur = new LemurService(params);
    this.realtime = new RealtimeTranscriberFactory(params);

    this.streaming = new StreamingTranscriberFactory({
      ...params,
      baseUrl: params.streamingBaseUrl || defaultStreamingUrl,
    });

    let syncBaseUrl = params.syncBaseUrl || defaultSyncUrl;
    if (syncBaseUrl.endsWith("/")) {
      syncBaseUrl = syncBaseUrl.slice(0, -1);
    }
    this.sync = new SyncTranscriber({
      ...params,
      baseUrl: syncBaseUrl,
    });
  }
}

export {
  AssemblyAI,
  SyncTranscriber,
  SyncTranscriptError,
  LemurService,
  RealtimeTranscriberFactory,
  RealtimeTranscriber,
  RealtimeServiceFactory,
  RealtimeService,
  TranscriptService,
  FileService,
  StreamingTranscriber,
  DualChannelCapture,
  EnergyVad,
  LinearResampler,
  VadTimeline,
  attributeTurn,
  attributeWord,
  rollUpTurnChannel,
  float32ToPcm16,
};
