/**
 * Cloud Function: generateTTS
 * Génère de l'audio TTS avec Google Cloud Text-to-Speech
 * Avec système de cache dans Firebase Storage
 */

const textToSpeech = require("@google-cloud/text-to-speech");
const crypto = require("crypto");
const logger = require("firebase-functions/logger");

/**
 * Génère un hash MD5 pour le texte (utilisé comme clé de cache)
 * @param {string} text - Texte à hasher
 * @return {string} Hash MD5
 */
function generateCacheKey(text, voiceConfig = {}) {
  const cacheString = JSON.stringify({
    text,
    lang: voiceConfig.languageCode || "fr-FR",
    voice: voiceConfig.name || "fr-FR-Standard-B",
  });
  return crypto.createHash("md5").update(cacheString).digest("hex");
}

/**
 * Génère l'audio TTS et le stocke dans Firebase Storage
 * @param {string} text - Texte à synthétiser
 * @param {object} storage - Instance Firebase Storage
 * @param {object} bucket - Bucket Firebase Storage
 * @param {object} voiceConfig - Configuration de la voix (optionnel)
 * @return {Promise<{audioUrl: string, cached: boolean}>}
 */
async function generateTTS(text, storage, bucket, voiceConfig = {}) {
  try {
    // Validation du texte
    if (!text || text.trim().length === 0) {
      throw new Error("Text cannot be empty");
    }

    if (text.length > 5000) {
      throw new Error("Text too long (max 5000 characters)");
    }

    // Configuration par défaut de la voix
    const defaultVoiceConfig = {
      languageCode: "fr-FR",
      name: "fr-FR-Standard-B", // Voix masculine française (Standard = gratuit)
      ssmlGender: "MALE",
    };

    const finalVoiceConfig = {...defaultVoiceConfig, ...voiceConfig};

    // Générer la clé de cache
    const cacheKey = generateCacheKey(text, finalVoiceConfig);
    const fileName = `tts-cache/${cacheKey}.mp3`;
    const file = bucket.file(fileName);

    // Vérifier si le fichier existe déjà dans le cache
    const [exists] = await file.exists();

    if (exists) {
      logger.info("[generateTTS] ✓ Cache HIT", {cacheKey, text: text.substring(0, 50)});

      // Générer une URL signée valide 7 jours
      const [url] = await file.getSignedUrl({
        action: "read",
        expires: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7 jours
      });

      return {
        audioUrl: url,
        cached: true,
        cacheKey,
      };
    }

    logger.info("[generateTTS] ○ Cache MISS - Generating audio", {
      cacheKey,
      text: text.substring(0, 50),
      voice: finalVoiceConfig.name,
    });

    // Créer le client Text-to-Speech
    const client = new textToSpeech.TextToSpeechClient();

    // Configuration de la requête
    const request = {
      input: {text: text},
      voice: finalVoiceConfig,
      audioConfig: {
        audioEncoding: "MP3",
        speakingRate: 0.9, // Légèrement plus lent pour meilleure compréhension
        pitch: -2.0, // Voix un peu plus grave
        volumeGainDb: 0.0,
      },
    };

    // Appeler l'API Google Cloud TTS
    const [response] = await client.synthesizeSpeech(request);

    if (!response.audioContent) {
      throw new Error("No audio content returned from TTS API");
    }

    logger.info("[generateTTS] ✓ Audio generated", {
      size: response.audioContent.length,
    });

    // Sauvegarder dans Firebase Storage
    await file.save(response.audioContent, {
      metadata: {
        contentType: "audio/mpeg",
        metadata: {
          text: text.substring(0, 100), // Premier 100 caractères pour debug
          voice: finalVoiceConfig.name,
          generatedAt: new Date().toISOString(),
        },
      },
    });

    logger.info("[generateTTS] ✓ Audio cached", {fileName});

    // Générer une URL signée
    const [url] = await file.getSignedUrl({
      action: "read",
      expires: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7 jours
    });

    return {
      audioUrl: url,
      cached: false,
      cacheKey,
    };
  } catch (error) {
    logger.error("[generateTTS] ✗ Error", {
      error: error.message,
      code: error.code,
      text: text?.substring(0, 50),
    });

    throw error;
  }
}

module.exports = {generateTTS, generateCacheKey};

