/**
 * 音频保存服务
 * 用于生成和保存示例语音文件
 */

class AudioSaveService {
  constructor() {
    this.audioContext = null
    this.synthesis = window.speechSynthesis
    this.init()
  }

  /**
   * 初始化音频服务
   */
  async init() {
    try {
      if (window.AudioContext || window.webkitAudioContext) {
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)()
      }
    } catch (error) {
      console.error('音频服务初始化失败:', error)
    }
  }

  /**
   * 生成语音文件
   * @param {string} text 要转换的文本
   * @param {string} filename 文件名
   * @returns {Promise<Blob>} 音频文件Blob
   */
  async generateAudioFile(text, filename) {
    return new Promise((resolve, reject) => {
      try {
        // 使用Web Speech API生成语音
        if (this.synthesis) {
          const utterance = new SpeechSynthesisUtterance(text)
          utterance.lang = 'en-US'
          utterance.rate = 0.9
          utterance.pitch = 1.0
          utterance.volume = 1.0

          // 创建音频录制
          const mediaRecorder = new MediaRecorder(new MediaStream())
          const audioChunks = []

          mediaRecorder.ondataavailable = (event) => {
            audioChunks.push(event.data)
          }

          mediaRecorder.onstop = () => {
            const audioBlob = new Blob(audioChunks, { type: 'audio/wav' })
            resolve(audioBlob)
          }

          utterance.onend = () => {
            mediaRecorder.stop()
          }

          utterance.onerror = (error) => {
            reject(new Error('语音生成失败: ' + error))
          }

          this.synthesis.speak(utterance)
        } else {
          // 备用方案：生成简单的音频文件
          this.generateSimpleAudio(text).then(resolve).catch(reject)
        }
      } catch (error) {
        reject(error)
      }
    })
  }

  /**
   * 生成简单的音频文件（备用方案）
   */
  async generateSimpleAudio(text) {
    return new Promise((resolve, reject) => {
      try {
        if (!this.audioContext) {
          reject(new Error('音频上下文不可用'))
          return
        }

        // 创建音频数据
        const sampleRate = 44100
        const duration = Math.min(text.length * 0.1, 3) // 根据文本长度调整时长
        const samples = sampleRate * duration

        // 创建音频缓冲区
        const audioBuffer = this.audioContext.createBuffer(1, samples, sampleRate)
        const channelData = audioBuffer.getChannelData(0)

        // 生成音频数据（简单的正弦波）
        for (let i = 0; i < samples; i++) {
          const frequency = 440 + (i % 100) // 变化的频率
          channelData[i] = Math.sin(2 * Math.PI * frequency * i / sampleRate) * 0.3
        }

        // 转换为Blob
        const wavBlob = this.audioBufferToWav(audioBuffer)
        resolve(wavBlob)
      } catch (error) {
        reject(error)
      }
    })
  }

  /**
   * 将AudioBuffer转换为WAV格式
   */
  audioBufferToWav(buffer) {
    const length = buffer.length
    const numberOfChannels = buffer.numberOfChannels
    const sampleRate = buffer.sampleRate
    const arrayBuffer = new ArrayBuffer(44 + length * numberOfChannels * 2)
    const view = new DataView(arrayBuffer)

    // WAV文件头
    const writeString = (offset, string) => {
      for (let i = 0; i < string.length; i++) {
        view.setUint8(offset + i, string.charCodeAt(i))
      }
    }

    writeString(0, 'RIFF')
    view.setUint32(4, 36 + length * numberOfChannels * 2, true)
    writeString(8, 'WAVE')
    writeString(12, 'fmt ')
    view.setUint32(16, 16, true)
    view.setUint16(20, 1, true)
    view.setUint16(22, numberOfChannels, true)
    view.setUint32(24, sampleRate, true)
    view.setUint32(28, sampleRate * numberOfChannels * 2, true)
    view.setUint16(32, numberOfChannels * 2, true)
    view.setUint16(34, 16, true)
    writeString(36, 'data')
    view.setUint32(40, length * numberOfChannels * 2, true)

    // 写入音频数据
    let offset = 44
    for (let i = 0; i < length; i++) {
      for (let channel = 0; channel < numberOfChannels; channel++) {
        const sample = Math.max(-1, Math.min(1, buffer.getChannelData(channel)[i]))
        view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true)
        offset += 2
      }
    }

    return new Blob([arrayBuffer], { type: 'audio/wav' })
  }

  /**
   * 保存音频文件到本地
   * @param {Blob} audioBlob 音频文件
   * @param {string} filename 文件名
   */
  saveAudioFile(audioBlob, filename) {
    try {
      const url = URL.createObjectURL(audioBlob)
      const link = document.createElement('a')
      link.href = url
      link.download = filename
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(url)
      
      console.log('音频文件已保存:', filename)
      return true
    } catch (error) {
      console.error('保存音频文件失败:', error)
      return false
    }
  }

  /**
   * 批量保存示例音频
   * @param {Array} examples 示例数组
   */
  async saveAllExampleAudios(examples) {
    const results = []
    
    for (let i = 0; i < examples.length; i++) {
      const example = examples[i]
      try {
        console.log(`正在生成音频 ${i + 1}/${examples.length}: ${example.name}`)
        
        const audioBlob = await this.generateAudioFile(example.english, `${example.name}.wav`)
        const filename = `${example.name}_${example.english.substring(0, 20).replace(/[^a-zA-Z0-9]/g, '_')}.wav`
        
        const success = this.saveAudioFile(audioBlob, filename)
        results.push({
          name: example.name,
          success,
          filename
        })
        
        // 添加延迟避免浏览器限制
        await new Promise(resolve => setTimeout(resolve, 500))
        
      } catch (error) {
        console.error(`生成音频失败 ${example.name}:`, error)
        results.push({
          name: example.name,
          success: false,
          error: error.message
        })
      }
    }
    
    return results
  }
}

// 创建单例实例
const audioSaveService = new AudioSaveService()

export default audioSaveService 
