const KEY = import.meta.env.VITE_AZURE_SPEECH_KEY as string | undefined
const REGION = import.meta.env.VITE_AZURE_SPEECH_REGION as string | undefined
// 美式男声,口齿清晰、随和。备选(都是 en-US-*Neural):
//   GuyNeural / AndrewNeural / ChristopherNeural / TonyNeural(男)
//   JennyNeural / EmmaNeural / AvaNeural(女,清晰度也高)
const VOICE = 'en-US-JennyNeural'
const FORMAT = 'audio-24khz-48kbitrate-mono-mp3'
// 默认偏自然偏快;调慢改 -10%、调更快改 +25% 之类。
const RATE = '+10%'

/**
 * Synthesize English text via Azure Speech REST.
 * Returns an MP3 Blob. Throws on credential / network / non-2xx.
 *
 * Pass an AbortSignal so callers (the audio player) can cancel
 * an in-flight synthesis when the user starts recording or
 * triggers a different playback.
 */
export async function synthesize(text: string, signal?: AbortSignal): Promise<Blob> {
  if (!KEY || !REGION) {
    throw new Error('Azure Speech credentials not configured (VITE_AZURE_SPEECH_KEY / VITE_AZURE_SPEECH_REGION)')
  }

  const ssml =
    `<speak version='1.0' xml:lang='en-US'>` +
    `<voice name='${VOICE}'>` +
    `<prosody rate='${RATE}'>${escapeXml(text)}</prosody>` +
    `</voice>` +
    `</speak>`

  const res = await fetch(
    `https://${REGION}.tts.speech.microsoft.com/cognitiveservices/v1`,
    {
      method: 'POST',
      signal,
      headers: {
        'Ocp-Apim-Subscription-Key': KEY,
        'Content-Type': 'application/ssml+xml',
        'X-Microsoft-OutputFormat': FORMAT,
        'User-Agent': 'PPT-EnglishSpeaking',
      },
      body: ssml,
    },
  )

  if (!res.ok) {
    throw new Error(`Azure TTS failed: ${res.status} ${res.statusText}`)
  }
  return res.blob()
}

function escapeXml(s: string): string {
  return s.replace(/[<>&'"]/g, c => ({
    '<': '&lt;',
    '>': '&gt;',
    '&': '&amp;',
    "'": '&apos;',
    '"': '&quot;',
  }[c]!))
}
