/**
 * Local Whisper STT service using nodejs-whisper.
 * Used as a fallback when no OpenAI API key is configured (local mode).
 * Requires ffmpeg to be installed on the system.
 */

let whisperAvailable = null; // null = unchecked, true/false
let modelReady = false;

/**
 * Check if nodejs-whisper and ffmpeg are available.
 */
async function isWhisperAvailable() {
  if (whisperAvailable !== null) return whisperAvailable;

  try {
    // Check if nodejs-whisper can be imported
    await import('nodejs-whisper');

    // Check if ffmpeg is available
    const { execSync } = await import('child_process');
    execSync('ffmpeg -version', { stdio: 'pipe', timeout: 5000 });

    whisperAvailable = true;
  } catch {
    whisperAvailable = false;
  }

  return whisperAvailable;
}

/**
 * Ensure the whisper model is downloaded.
 * Downloads the tiny.en model (~75MB) on first use.
 */
async function ensureWhisperModel() {
  if (modelReady) return true;

  const available = await isWhisperAvailable();
  if (!available) return false;

  try {
    const { nodeWhisper } = await import('nodejs-whisper');
    // Attempt to download model if not present
    await nodeWhisper.downloadModel('tiny.en');
    modelReady = true;
    return true;
  } catch (err) {
    console.warn('[WhisperService] Failed to download model:', err.message);
    return false;
  }
}

/**
 * Transcribe audio using local nodejs-whisper.
 * @param {string} audioFilePath - Path to the audio file (WAV, MP3, etc.)
 * @returns {Promise<string|null>} Transcribed text, or null if failed
 */
async function transcribeLocal(audioFilePath) {
  const ready = await ensureWhisperModel();
  if (!ready) return null;

  try {
    const { nodeWhisper } = await import('nodejs-whisper');
    const result = await nodeWhisper(audioFilePath, {
      modelName: 'tiny.en',
      autoDownloadModelName: 'tiny.en',
      whisperOptions: {
        outputInText: true,
        language: 'en',
      }
    });

    // nodejs-whisper returns array of segments or text
    if (typeof result === 'string') return result.trim();
    if (Array.isArray(result)) return result.map(s => s.speech || s.text || '').join(' ').trim();
    return null;
  } catch (err) {
    console.error('[WhisperService] Transcription error:', err.message);
    return null;
  }
}

export { isWhisperAvailable, ensureWhisperModel, transcribeLocal };
