// utils/visemes.ts
// Simple phoneme to viseme mapping based on text analysis
// This is a basic implementation - you might want to use a more sophisticated library

interface VisemeMapping {
  [key: string]: number;
}

// Microsoft viseme IDs mapping
const PHONEME_TO_VISEME: VisemeMapping = {
  // Silence
  'sil': 0,
  // Consonants
  'p': 1, 'b': 1, 'm': 1,
  'f': 2, 'v': 2,
  'th': 3, 'dh': 3,
  't': 4, 'd': 4, 'n': 4, 'l': 4,
  's': 5, 'z': 5,
  'sh': 6, 'zh': 6, 'ch': 6, 'jh': 6,
  'k': 7, 'g': 7, 'ng': 7,
  'r': 8,
  // Vowels
  'aa': 9, 'ao': 9,
  'ih': 10, 'iy': 10,
  'uw': 11, 'uh': 11,
  'ah': 12, 'ax': 12,
  'ae': 13,
  'eh': 14, 'ey': 14,
  'ow': 15, 'oy': 15,
  'ay': 16, 'aw': 16,
  'er': 17,
  'w': 18, 'y': 18,
};

// Simple text-to-phoneme approximation
function textToPhonemes(text: string): string[] {
  // This is a very basic implementation
  // For production, consider using a proper phoneme library like espeak-ng
  const words = text.toLowerCase().replace(/[^\w\s]/g, '').split(/\s+/);
  const phonemes: string[] = [];
  
  for (const word of words) {
    // Basic vowel/consonant detection
    for (let i = 0; i < word.length; i++) {
      const char = word[i];
      if ('aeiou'.includes(char)) {
        phonemes.push('ah'); // Generic vowel
      } else if (char === 'r') {
        phonemes.push('r');
      } else if (char === 'l') {
        phonemes.push('l');
      } else if (char === 'th') {
        phonemes.push('th');
        i++; // Skip next char
      } else if ('pbm'.includes(char)) {
        phonemes.push('p');
      } else if ('fv'.includes(char)) {
        phonemes.push('f');
      } else if ('tdnl'.includes(char)) {
        phonemes.push('t');
      } else if ('sz'.includes(char)) {
        phonemes.push('s');
      } else if ('kg'.includes(char)) {
        phonemes.push('k');
      } else {
        phonemes.push('t'); // Default consonant
      }
    }
    phonemes.push('sil'); // Silence between words
  }
  
  return phonemes;
}

export function generateApproximateVisemes(text: string, audioDurationMs: number): [number, number][] {
  const phonemes = textToPhonemes(text);
  const visemes: [number, number][] = [];
  
  // Distribute phonemes evenly across the audio duration
  const timePerPhoneme = audioDurationMs / phonemes.length;
  
  phonemes.forEach((phoneme, index) => {
    const visemeId = PHONEME_TO_VISEME[phoneme] || 0;
    const timestamp = index * timePerPhoneme;
    visemes.push([timestamp, visemeId]);
  });
  
  return visemes;
}

// Alternative: Use Web Speech API for better phoneme detection (client-side only)
export function getAudioDuration(audioBuffer: Buffer): Promise<number> {
  // This would need to be implemented using a library like node-ffprobe
  // For now, return an estimate based on typical speech rate
  return Promise.resolve(audioBuffer.length / 16000 * 1000); // Rough estimate
}