/**
 * minimax-key2 TTS 测试脚本
 * 使用 minimax-key2 配置发送 2 个 "你好" TTS 请求
 * 流程: 创建任务 → 轮询状态 → 下载音频
 */

import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

// ============================================================
// minimax-key2 配置 (来自 server/src/config/models.json)
// ============================================================
const CONFIG = {
  apiKey: 'sk-cp-BOVwOolqOEmHycg8MzDX_UgQ_bDEK3snjPUFuwolUCb_TxMxhhlAfYhTT0_tqRvEz5K56xpl-aOoJtj97MuAY4UIA-PCQLVetUCY56i8LFimNuQqrrq5xWA',
  ttsApiPath: 'https://api.minimaxi.com',
  model: 'speech-2.8-hd',
  voice: 'audiobook_female_1', // Cherry
};

const OUTPUT_DIR = path.resolve(__dirname, '../test-results/minimax-key2-tts');
const TEXT = '你好';

// ============================================================
// TAR 解包工具：从 tar buffer 中提取 MP3
// ============================================================
function extractMp3FromTar(buffer: Buffer): Buffer | null {
  let offset = 0;
  while (offset < buffer.length - 512) {
    const nameSlice = buffer.subarray(offset, offset + 100);
    const nameEnd = nameSlice.indexOf(0);
    const filename = nameEnd >= 0 ? Buffer.from(nameSlice.subarray(0, nameEnd)).toString() : nameSlice.toString();

    if (!filename || filename.trim().length === 0) break;

    const sizeStr = Buffer.from(buffer.subarray(offset + 124, offset + 135)).toString().trim();
    const fileSize = parseInt(sizeStr, 8);
    const contentOffset = offset + 512;

    if (filename.endsWith('.mp3')) {
      console.log(`  📦 从 tar 中提取 ${filename} (${fileSize} bytes)`);
      return Buffer.from(buffer.subarray(contentOffset, contentOffset + fileSize));
    }

    const paddedSize = Math.ceil(fileSize / 512) * 512;
    offset = contentOffset + paddedSize;
  }
  return null;
}

// ============================================================
// 单个 TTS 请求完整流程
// ============================================================
async function ttsRequest(text: string, requestId: number): Promise<void> {
  const tag = `[请求#${requestId}]`;
  console.log(`\n${'='.repeat(60)}`);
  console.log(`${tag} 开始 TTS 合成: "${text}"`);
  console.log(`${'='.repeat(60)}`);

  // ---- 步骤 1: 创建异步任务 ----
  console.log(`${tag} 📤 步骤1: 创建异步任务...`);
  const createRes = await fetch(`${CONFIG.ttsApiPath}/v1/t2a_async_v2`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${CONFIG.apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: CONFIG.model,
      text,
      voice_setting: {
        voice_id: CONFIG.voice,
        speed: 1,
        vol: 1,
        pitch: 1,
      },
      audio_setting: {
        audio_sample_rate: 32000,
        bitrate: 128000,
        format: 'mp3',
        channel: 1,
      },
    }),
  });

  const createData: any = await createRes.json();
  console.log(`${tag} 响应:`, JSON.stringify(createData, null, 2));

  if (createData.base_resp?.status_code !== 0) {
    throw new Error(`${tag} 创建任务失败: ${createData.base_resp?.status_msg || JSON.stringify(createData)}`);
  }

  const task_id = String(createData.task_id);
  const task_token = createData.task_token;
  console.log(`${tag} ✅ 任务已创建, task_id: ${task_id}`);

  // ---- 步骤 2: 轮询任务状态 ----
  console.log(`${tag} 🔄 步骤2: 轮询中...`);
  const maxPollMs = 2 * 60 * 1000; // 最多 2 分钟
  const pollInterval = 3000;
  const startTime = Date.now();
  let file_id: string | null = null;

  while (Date.now() - startTime < maxPollMs) {
    const queryRes = await fetch(
      `${CONFIG.ttsApiPath}/v1/query/t2a_async_query_v2?task_id=${task_id}&task_token=${task_token}`,
      { headers: { 'Authorization': `Bearer ${CONFIG.apiKey}` } }
    );
    const queryData: any = await queryRes.json();
    const status = queryData.status;
    process.stdout.write(`\r${tag}   状态: ${status} (${Math.round((Date.now() - startTime) / 1000)}s)`);

    if (status === 'Success') {
      file_id = queryData.file_id ? String(queryData.file_id) : null;
      console.log(`\n${tag} ✅ 任务完成, file_id: ${file_id}`);
      break;
    }
    if (status === 'Failed') {
      throw new Error(`${tag} 任务失败: ${queryData.status_msg || '未知错误'}`);
    }
    await new Promise(r => setTimeout(r, pollInterval));
  }

  if (!file_id) throw new Error(`${tag} 轮询超时`);

  // ---- 步骤 3: 下载音频 ----
  console.log(`${tag} ⬇️ 步骤3: 下载音频...`);
  const downloadRes = await fetch(
    `${CONFIG.ttsApiPath}/v1/files/retrieve_content?file_id=${file_id}`,
    { headers: { 'Authorization': `Bearer ${CONFIG.apiKey}` } }
  );
  const arrayBuffer = await downloadRes.arrayBuffer();
  const buffer = Buffer.from(arrayBuffer);

  const mp3Data = extractMp3FromTar(buffer);
  if (!mp3Data) throw new Error(`${tag} tar 中未找到 MP3 文件`);

  if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR, { recursive: true });
  const outputPath = path.join(OUTPUT_DIR, `output-${requestId}.mp3`);
  fs.writeFileSync(outputPath, mp3Data);
  console.log(`${tag} ✅ 音频已保存: ${outputPath} (${mp3Data.length} bytes)`);
}

// ============================================================
// 主流程：同时发送 2 个 TTS 请求
// ============================================================
async function main() {
  console.log('🚀 MiniMax Key2 TTS 测试 - 并行 2 个请求');
  console.log(`📝 文本: "${TEXT}"`);
  console.log(`🎤 音色: ${CONFIG.voice}`);
  console.log(`🤖 模型: ${CONFIG.model}`);
  console.log(`📁 输出: ${OUTPUT_DIR}`);

  const startTime = Date.now();

  try {
    await Promise.all([
      ttsRequest(TEXT, 1),
      ttsRequest(TEXT, 2),
    ]);

    const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
    console.log(`\n${'='.repeat(60)}`);
    console.log(`🎉 全部完成! 耗时: ${elapsed}s`);
    console.log(`📂 输出目录: ${OUTPUT_DIR}`);
  } catch (err: any) {
    console.error(`\n❌ 测试失败:`, err.message);
    process.exit(1);
  }
}

main();
