// 此脚本运行于WebWorker之下

import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile, toBlobURL } from '@ffmpeg/util';

let ffmpeg = null;

// 初始化FFmpeg
async function initFFmpeg() {
  if (ffmpeg) return ffmpeg;
  
  try {
    console.log('Initializing FFmpeg...');
    ffmpeg = new FFmpeg();
    
    // Load FFmpeg core files from the official CDN
    console.log('Loading FFmpeg core');
    const baseURL = '/ffmpeg';
    await ffmpeg.load({
      coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
      wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
      log: true
    });
    
    console.log('FFmpeg loaded successfully');
    return ffmpeg;
  } catch (error) {
    console.error('FFmpeg initialization error:', error);
    throw error;
  }
}

// 解码mp3数据为pcm数据
async function decode_mp3(req) {
  try {
    const ffmpeg = await initFFmpeg();
    
    // 检查FFmpeg是否已加载
    if (!ffmpeg || !ffmpeg.loaded) {
      // 如果没有加载完成，就一直等待
      while (!ffmpeg || !ffmpeg.loaded) {
        await new Promise(resolve => setTimeout(resolve, 100));
      }
      // throw new Error('FFmpeg not properly loaded');
    }
    
    console.log('FFmpeg is ready, starting MP3 decode...');
    
    // 将MP3数据写入FFmpeg
    let fname = req.name;
    await ffmpeg.writeFile(fname + '.mp3', req.data);
    
    // 使用FFmpeg解码MP3为PCM s16le格式
    await ffmpeg.exec([
      '-i', fname + '.mp3',
      '-f', 's16le',
      '-acodec', 'pcm_s16le',
      '-ar', '16000',
      '-ac', '1',
      fname + '-output.pcm'
    ]);
    
    // 读取解码后的PCM数据
    const pcmData = await ffmpeg.readFile('output.pcm');
    
    // 清理临时文件
    await ffmpeg.deleteFile(fname + '.mp3');
    await ffmpeg.deleteFile(fname + '-output.pcm');
    
    // 将Uint8Array转换为Uint16Array (s16le格式)
    const uint8Array = new Uint8Array(pcmData);
    const uint16Array = new Uint16Array(uint8Array.buffer, uint8Array.byteOffset, uint8Array.length / 2);
    
    return uint8Array;
  } catch (error) {
    console.error('MP3 decode error:', error);
    // 返回空数组作为fallback
    return new Uint16Array(0);
  }
}

/**
 * 模拟 Recorder.getRecordAnalyseData 的功能
 * @param {Int16Array} pcmData PCM 原始数据，s16le 格式
 * @returns {Uint8Array} 长度固定 1024，范围 0–255 的波形数据
 */
function getRecordAnalyseData(pcmData) {
    const BUF_LEN = 800;
    const out = new Uint8Array(BUF_LEN);

    const pcm = [];
    for (let i = 0; i < pcmData.length; i+=2) {
      let h = pcmData[i] & 0xff;
      let l = pcmData[i + 1] & 0xff;
      let p = (l << 8) | h;
      // 如果p是负数，则取反
      if (p & 0x8000) p = (p & 0x7fff) - 0x8000;
      pcm.push(p);
    }
    const len = pcm.length;
    if (len === 0) return out.fill(128); // 空数据，填充中值

    const step = len / BUF_LEN;

    let rst = [];
    for (let i = 0; i < BUF_LEN; i++) {
        const start = Math.floor(i * step);
        const end = Math.min(Math.floor((i + 1) * step), len);

        // 计算这一段的平均值（保持正负号，显示真实波形）
        let sum = 0;
        for (let j = start; j < end; j++)
        {
          sum += Math.abs(pcm[j]);
        }
        const avg = Math.floor(sum / (end - start));
        rst.push(avg);

        // 将平均值从 [-32768, 32767] 映射到 [0, 255]
        // 128 是中心线（静音），0是最负值，255是最正值
        const normalized = avg / 32767; // 归一化到 [0, 1]
        out[i] = Math.max(0, Math.min(127, Math.round(normalized * 127)));
    }
    return out;
}

// 接收worker的消息，发过来的消息是mp3数据片段，帮我完成解码和波形分析并返回数据即可
self.addEventListener('message', async function(e) {
  try {
    const mp3Data = e.data;
    
    // 解码MP3数据为PCM格式
    const pcmData = await decode_mp3(mp3Data);
    
    // 生成波形分析数据
    const waveformData = getRecordAnalyseData(pcmData);
    
    // 返回结果给主线程
    self.postMessage({
      success: true,
      waveformData: waveformData,
      pcmData: pcmData
    });
    
  } catch (error) {
    console.error('Worker error:', error);
    
    // 返回错误信息给主线程
    self.postMessage({
      success: false,
      error: error.message
    });
  }
}); 