/**
 * 火山引擎语音识别服务
 * 提供前端直接调用火山引擎API的功能
 */

import { volcengineConfig } from '../config/volcengine.js'

class VolcengineService {
  constructor() {
    // 使用配置文件
    this.config = volcengineConfig
  }

  /**
   * 语音识别主方法
   * @param {File|Blob} audioFile 音频文件
   * @param {string} language 语言代码，默认英文
   * @returns {Promise<string>} 识别结果
   */
  async speechToText(audioFile, language = 'en-US') {
    try {
      console.log('=== 开始语音识别 ===')
      console.log('音频文件:', audioFile)
      console.log('语言:', language)
      
      // 验证文件格式
      this.validateAudioFormat(audioFile)
      console.log('文件格式验证通过')
      
      // 将音频转换为Base64
      const base64Audio = await this.blobToBase64(audioFile)
      console.log('音频转Base64完成，长度:', base64Audio.length)
      
      // 第一步：提交任务
      const taskId = await this.submitTask(base64Audio, audioFile, language)
      console.log('任务提交成功，ID:', taskId)
      
      // 第二步：查询结果
      const result = await this.queryResult(taskId)
      console.log('查询结果:', result)
      
      return result
      
    } catch (error) {
      console.error('语音识别失败:', error)
      throw new Error(`语音识别失败: ${error.message}`)
    }
  }

  /**
   * 验证音频文件格式
   * @param {File|Blob} file 音频文件
   */
  validateAudioFormat(file) {
    const fileName = file.name ? file.name.toLowerCase() : ''
    const supportedFormats = ['.mp3', '.wav', '.m4a', '.aac']
    
    if (fileName && !supportedFormats.some(format => fileName.endsWith(format))) {
      throw new Error('只支持MP3、WAV、M4A、AAC格式文件')
    }
  }

  /**
   * 将Blob转换为Base64
   * @param {Blob} blob 音频blob
   * @returns {Promise<string>} Base64字符串
   */
  blobToBase64(blob) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => {
        const base64 = reader.result.split(',')[1] // 移除data:audio/wav;base64,前缀
        resolve(base64)
      }
      reader.onerror = reject
      reader.readAsDataURL(blob)
    })
  }

  /**
   * 提交语音识别任务
   * @param {string} base64Audio Base64编码的音频数据
   * @param {File|Blob} audioFile 原始音频文件
   * @param {string} language 语言代码
   * @returns {Promise<string>} 任务ID
   */
  async submitTask(base64Audio, audioFile, language) {
    const requestBody = {
      app: {
        appid: this.config.appId,
        token: this.config.token,
        cluster: this.config.cluster
      },
      user: {
        uid: "demo_user"
      },
      audio: {
        format: this.getAudioFormat(audioFile),
        data: base64Audio
      },
      additions: {
        with_speaker_info: "False",
        language: "en-US" // 设置为英文（美式英语）
      }
    }

    console.log('提交任务请求体:', requestBody)
    
    const response = await fetch(`${this.config.apiUrl}/submit`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer; ${this.config.token}`,
        'Connection': 'keep-alive'
      },
      body: JSON.stringify(requestBody)
    })

    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`提交任务失败: HTTP ${response.status} - ${errorText}`)
    }

    const result = await response.json()
    console.log('提交任务响应:', result)

    if (result.resp && result.resp.id) {
      return result.resp.id
    } else {
      throw new Error('提交任务失败：未获取到任务ID')
    }
  }

  /**
   * 查询语音识别结果
   * @param {string} taskId 任务ID
   * @returns {Promise<string>} 识别结果
   */
  async queryResult(taskId) {
    const requestBody = {
      appid: this.config.appId,
      token: this.config.token,
      id: taskId,
      cluster: this.config.cluster
    }

    console.log('查询任务请求体:', requestBody)
    
    const response = await fetch(`${this.config.apiUrl}/query`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer; ${this.config.token}`,
        'Connection': 'keep-alive'
      },
      body: JSON.stringify(requestBody)
    })

    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`查询任务失败: HTTP ${response.status} - ${errorText}`)
    }

    const result = await response.json()
    console.log('查询任务响应:', result)

    if (result.resp) {
      const { code, text } = result.resp
      
      switch (code) {
        case 1000:
          console.log('转换成功')
          return text
        case 2000:
        case 2001:
        case 2002:
          console.log('任务处理中，等待500ms后重试')
          await new Promise(resolve => setTimeout(resolve, 500))
          return this.queryResult(taskId) // 递归重试
        default:
          console.log('转换失败，错误码:', code)
          return '语音识别失败'
      }
    } else {
      throw new Error('查询任务失败：响应格式错误')
    }
  }

  /**
   * 获取音频格式
   * @param {File|Blob} file 音频文件
   * @returns {string} 音频格式
   */
  getAudioFormat(file) {
    const type = file.type || ''
    const fileName = file.name ? file.name.toLowerCase() : ''
    
    if (type.includes('mp3') || fileName.endsWith('.mp3')) return 'mp3'
    if (type.includes('wav') || fileName.endsWith('.wav')) return 'wav'
    if (type.includes('m4a') || fileName.endsWith('.m4a')) return 'm4a'
    if (type.includes('aac') || fileName.endsWith('.aac')) return 'aac'
    
    return 'wav' // 默认格式
  }

  /**
   * 发送HTTP请求到火山引擎
   * @param {Object} requestBody 请求体
   * @returns {Promise<Object>} 响应结果
   */
  async sendRequest(requestBody) {
    console.log('发送请求到:', this.config.apiUrl)
    console.log('请求头:', {
      'Content-Type': 'application/json',
      'Authorization': this.generateAuthorization(),
      'X-App-Id': this.config.appId,
      'X-Cluster': this.config.cluster
    })
    console.log('请求体:', requestBody)
    
    try {
      const response = await fetch(this.config.apiUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': this.generateAuthorization(),
          'X-App-Id': this.config.appId,
          'X-Cluster': this.config.cluster,
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        },
        body: JSON.stringify(requestBody)
      })

      console.log('响应状态:', response.status)
      console.log('响应头:', Object.fromEntries(response.headers.entries()))

      if (!response.ok) {
        const errorText = await response.text()
        console.error('响应错误:', errorText)
        throw new Error(`HTTP ${response.status}: ${response.statusText} - ${errorText}`)
      }

      const result = await response.json()
      console.log('响应结果:', result)
      return result
    } catch (error) {
      console.error('请求失败:', error)
      throw error
    }
  }

  /**
   * 生成授权头
   * @returns {string} 授权头字符串
   */
  generateAuthorization() {
    // 使用token作为授权头
    return `Bearer ${this.config.token}`
  }

  /**
   * 解析响应结果
   * @param {Object} response 火山引擎响应
   * @returns {string} 识别结果文本
   */
  parseResponse(response) {
    try {
      // 根据火山引擎的响应格式解析结果
      if (response && response.result) {
        return response.result
      }
      
      if (response && response.data && response.data.result) {
        return response.data.result
      }
      
      throw new Error('响应格式不正确')
    } catch (error) {
      console.error('解析响应失败:', error)
      throw new Error('解析响应失败')
    }
  }

  /**
   * 更新配置
   * @param {Object} newConfig 新的配置对象
   */
  updateConfig(newConfig) {
    this.config = { ...this.config, ...newConfig }
  }
}

// 创建单例实例
const volcengineService = new VolcengineService()

export default volcengineService 
