import type { OutboundAttachment } from '../channels/types.js';

export type TtsOutputFormat = 'mp3' | 'wav' | 'opus';

export interface TtsSynthesisConfig {
  endpoint?: string;
  apiKey?: string;
  model?: string;
  voice?: string;
  format?: TtsOutputFormat;
}

function outputFormatToMimeType(format: TtsOutputFormat): string {
  switch (format) {
    case 'wav':
      return 'audio/wav';
    case 'opus':
      return 'audio/ogg';
    case 'mp3':
    default:
      return 'audio/mpeg';
  }
}

function outputFormatToExtension(format: TtsOutputFormat): string {
  switch (format) {
    case 'wav':
      return 'wav';
    case 'opus':
      return 'ogg';
    case 'mp3':
    default:
      return 'mp3';
  }
}

/** Synthesize speech via an OpenAI-compatible /v1/audio/speech endpoint. */
export async function synthesizeSpeechAttachment(
  text: string,
  config: TtsSynthesisConfig,
): Promise<OutboundAttachment | null> {
  const trimmed = text.trim();
  if (!trimmed) {
    return null;
  }
  if (!config.endpoint) {
    return null;
  }

  const format = config.format ?? 'mp3';
  const model = config.model ?? 'gpt-4o-mini-tts';
  const voice = config.voice ?? 'alloy';

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
  };
  if (config.apiKey) {
    headers.Authorization = `Bearer ${config.apiKey}`;
  }

  const response = await fetch(config.endpoint, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      model,
      voice,
      input: trimmed,
      response_format: format,
    }),
  });

  if (!response.ok) {
    const detail = await response.text().catch(() => '');
    throw new Error(
      `TTS request failed: ${response.status} ${response.statusText}${detail ? ` - ${detail.slice(0, 200)}` : ''}`,
    );
  }

  const audioBytes = await response.arrayBuffer();
  const data = Buffer.from(audioBytes).toString('base64');
  const extension = outputFormatToExtension(format);

  return {
    mimeType: outputFormatToMimeType(format),
    data,
    filename: `flynn-reply-${Date.now()}.${extension}`,
  };
}
