import {
  IsBase64,
  IsIn,
  IsInt,
  IsString,
  MaxLength,
  Min,
} from 'class-validator';
import { ErrorCode } from '../../../common/errors/error-codes';

/** Containers OpenRouter's transcription endpoint accepts, and MediaRecorder can produce. */
export const VOICE_AUDIO_FORMATS = [
  'webm',
  'mp4',
  'm4a',
  'aac',
  'ogg',
  'wav',
  'mp3',
  'flac',
] as const;

export type VoiceAudioFormat = (typeof VOICE_AUDIO_FORMATS)[number];

/** Locales the app ships; a profile still has to be configured for one to be usable. */
export const VOICE_LOCALES = ['en', 'fa', 'nl'] as const;

export class ExtractVoiceDto {
  /** Base64 audio, no data: prefix. Well above a 2-minute opus clip (~400 KB). */
  @IsString()
  @IsBase64()
  // Both name their own code: the shared map sends `maxLength` to
  // VALIDATION_FIELD_REQUIRED and `isIn` to VALIDATION_LANGUAGE_INVALID, neither of which
  // is true here.
  @MaxLength(8_000_000, { message: ErrorCode.VOICE_CLIP_TOO_LONG })
  audio: string;

  @IsIn(VOICE_AUDIO_FORMATS, { message: ErrorCode.VOICE_UNSUPPORTED_FORMAT })
  format: VoiceAudioFormat;

  /** The clinician's IANA zone; "today" is derived from it, never sent by the client. */
  @IsString()
  @MaxLength(64)
  timeZone: string;

  /** Required, not optional — omitting it would bypass VOICE_MAX_RECORDING_MS entirely. */
  @IsInt()
  @Min(0)
  durationMs: number;

  /**
   * The locale the UI offered the microphone in. Sent explicitly because `user.language` can
   * diverge from the URL locale, and a mismatch transcribes Persian with an English hint and
   * anchors "next Thursday" to the wrong week start.
   */
  @IsIn(VOICE_LOCALES)
  locale: string;
}
