// Azure Text-to-Speech Service

const axios = require('axios');

class TTSService {
  constructor() {
    // Azure Speech Service configuration
    this.apiKey = process.env.AZURE_SPEECH_KEY || '';
    this.region = process.env.AZURE_SPEECH_REGION || 'eastus';
    this.endpoint = `https://${this.region}.tts.speech.microsoft.com/cognitiveservices/v1`;
    this.hasValidConfig = !!(this.apiKey && this.region);
    
    if (!this.hasValidConfig) {
      console.log('[TTS] Warning: Azure Speech credentials not configured. TTS will be disabled.');
      console.log('[TTS] Set AZURE_SPEECH_KEY and AZURE_SPEECH_REGION environment variables.');
    }
  }

  /**
   * Generate speech audio from text using Azure TTS
   * @param {string} text - Text to synthesize
   * @param {object} voiceConfig - Voice configuration { name, locale, style }
   * @returns {Promise<{success: boolean, audioUrl?: string, audioBase64?: string, error?: string}>}
   */
  async synthesize(text, voiceConfig) {
    if (!this.hasValidConfig) {
      return {
        success: false,
        error: 'Azure Speech credentials not configured'
      };
    }

    if (!text || text.trim().length === 0) {
      return {
        success: false,
        error: 'Empty text provided'
      };
    }

    try {
      // Build SSML (Speech Synthesis Markup Language)
      const ssml = this.buildSSML(text, voiceConfig);

      const response = await axios.post(this.endpoint, ssml, {
        headers: {
          'Ocp-Apim-Subscription-Key': this.apiKey,
          'Content-Type': 'application/ssml+xml',
          'X-Microsoft-OutputFormat': 'audio-48khz-192kbitrate-mono-mp3',
          'User-Agent': 'AiRPG/1.0'
        },
        responseType: 'arraybuffer',
        timeout: 30000
      });

      // Convert audio buffer to base64
      const audioBase64 = Buffer.from(response.data).toString('base64');
      const contentType = response.headers['content-type'] || 'audio/mpeg';

      return {
        success: true,
        audioBase64,
        contentType,
        voiceUsed: voiceConfig.name,
        textLength: text.length
      };

    } catch (error) {
      console.error('[TTS] Synthesis error:', error.message);
      
      if (error.response) {
        const statusCode = error.response.status;
        if (statusCode === 401) {
          return { success: false, error: 'Invalid Azure Speech API key' };
        } else if (statusCode === 403) {
          return { success: false, error: 'Azure Speech quota exceeded or region mismatch' };
        } else if (statusCode === 400) {
          return { success: false, error: 'Invalid SSML or voice configuration' };
        }
      }
      
      return { 
        success: false, 
        error: `TTS synthesis failed: ${error.message}` 
      };
    }
  }

  /**
   * Build SSML for Azure TTS
   */
  buildSSML(text, voiceConfig) {
    const { name, locale = 'en-US', style = 'general' } = voiceConfig;
    
    // Escape special XML characters
    const escapedText = text
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&apos;');

    // Check if voice supports styles
    const styleAttribute = style && style !== 'general' 
      ? ` style="${style}"` 
      : '';

    return `<?xml version="1.0"?>
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="${locale}">
  <voice name="${name}"${styleAttribute}>
    <mstts:audioprofile name="rendering-voice"/>
    <prosody rate="default" pitch="default" volume="default">
      ${escapedText}
    </prosody>
  </voice>
</speak>`;
  }

  /**
   * Synthesize multiple segments with different voices
   * @param {Array} segments - Array of { text, voiceConfig } objects
   * @returns {Promise<{success: boolean, audioSegments?: Array, error?: string}>}
   */
  async synthesizeBatch(segments) {
    if (!this.hasValidConfig) {
      return {
        success: false,
        error: 'Azure Speech credentials not configured'
      };
    }

    const results = [];
    
    for (const segment of segments) {
      const result = await this.synthesize(segment.text, segment.voiceConfig);
      
      if (!result.success) {
        console.error('[TTS] Batch segment failed:', result.error);
        results.push({
          ...segment,
          success: false,
          error: result.error
        });
      } else {
        results.push({
          ...segment,
          ...result,
          success: true
        });
      }
    }

    return {
      success: true,
      audioSegments: results
    };
  }

  /**
   * Get available voices from Azure
   */
  async getVoices() {
    if (!this.hasValidConfig) {
      return { success: false, error: 'Azure Speech credentials not configured', voices: [] };
    }

    try {
      const response = await axios.get(
        `https://${this.region}.tts.speech.microsoft.com/cognitiveservices/voices/list`,
        {
          headers: {
            'Ocp-Apim-Subscription-Key': this.apiKey
          },
          timeout: 10000
        }
      );

      return {
        success: true,
        voices: response.data
      };
    } catch (error) {
      console.error('[TTS] Get voices error:', error.message);
      return {
        success: false,
        error: error.message,
        voices: []
      };
    }
  }

  /**
   * Check if service is configured and healthy
   */
  async healthCheck() {
    if (!this.hasValidConfig) {
      return { healthy: false, reason: 'No credentials configured' };
    }

    try {
      const result = await this.getVoices();
      return {
        healthy: result.success,
        reason: result.success ? 'OK' : result.error,
        voiceCount: result.voices?.length || 0
      };
    } catch (error) {
      return { healthy: false, reason: error.message };
    }
  }
}

module.exports = TTSService;
