/**
 * TTS 请求日志完整性验证脚本
 *
 * 目的：
 *  1. 直接发 N 次 TTS API 请求（MiniMax + 阿里云）
 *  2. 验证每次请求都写入了 AiCallLog 数据库表
 *  3. 对比日志文件中的请求次数与数据库记录
 *  4. 检测是否有异常的大量请求或日志遗漏
 *
 * 用法：npx ts-node scripts/test-tts-logging.ts
 */

import axios from 'axios';
import { prisma } from '../src/models';
import { withAiLog } from '../src/services/ai-call-logger';
import * as fs from 'fs';
import * as path from 'path';

// ============ 配置 ============
const TEST_COUNT = 10;        // 每个供应商发多少条请求
const LOG_DIR = path.join(process.cwd(), '..', '..');
const LOG_FILE = path.join(process.cwd(), '..', 'tts-debug.log');

// 从 models.json 读取 API Key
const modelsConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'src', 'config', 'models.json'), 'utf-8'));
const minimaxVendor = modelsConfig.vendors?.minimax;
const bailianVendor = modelsConfig.vendors?.bailian;
const MINIMAX_API_KEY = minimaxVendor?.apiKey || '';
const BAILIAN_API_KEY = bailianVendor?.apiKey || '';

// ============ 主流程 ============
async function main() {
  console.log('╔══════════════════════════════════════════╗');
  console.log('║   TTS 请求日志完整性验证脚本              ║');
  console.log('╚══════════════════════════════════════════╝\n');

  // ---- Step 1: 记录测试前的数据库基线 ----
  const beforeCount = await prisma.aiCallLog.count();
  console.log(`[基线] 测试前 AiCallLog 总记录数: ${beforeCount}`);

  // ---- Step 2: 发 MiniMax TTS 请求（createTask）----
  console.log(`\n[测试] 发送 ${TEST_COUNT} 次 MiniMax createTask 请求...`);
  const miniMaxResults: string[] = [];
  for (let i = 0; i < TEST_COUNT; i++) {
    try {
      await withAiLog(
        () => axios.post('https://api.minimaxi.com/v1/t2a_async_v2', {
          model: 'speech-2.8-hd',
          text: `测试文本_${i + 1}，用于验证TTS请求日志完整性。`.repeat(5),
          voice_setting: { voice_id: 'audiobook_female_1', speed: 1, vol: 1, pitch: 1 },
          audio_setting: { audio_sample_rate: 32000, bitrate: 128000, format: 'mp3', channel: 1 },
        }, {
          headers: { 'Authorization': `Bearer ${MINIMAX_API_KEY}`, 'Content-Type': 'application/json' },
          timeout: 10000,
        }),
        { callType: 'tts_test_create', provider: 'minimax', model: 'speech-2.8-hd', textLen: 200 }
      );
      miniMaxResults.push(`#${i + 1}: 成功`);
    } catch (err: any) {
      const msg = err?.message?.substring(0, 60) || '未知错误';
      miniMaxResults.push(`#${i + 1}: 失败(${msg})`);
    }
  }

  // ---- Step 3: 发阿里云 TTS 请求（synthesize）----
  console.log(`\n[测试] 发送 ${TEST_COUNT} 次阿里云 synthesize 请求...`);
  const aliyunResults: string[] = [];
  for (let i = 0; i < TEST_COUNT; i++) {
    try {
      await withAiLog(
        () => axios.post('https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', {
          model: 'qwen3-tts-instruct-flash',
          input: { text: `测试文本_${i + 1}`.repeat(10), voice: 'Cherry', language_type: 'Chinese' },
        }, {
          headers: { 'Authorization': `Bearer ${BAILIAN_API_KEY}`, 'Content-Type': 'application/json' },
          timeout: 10000,
        }),
        { callType: 'tts_test_synthesize', provider: 'bailian', model: 'qwen3-tts-instruct-flash', textLen: 100 }
      );
      aliyunResults.push(`#${i + 1}: 成功`);
    } catch (err: any) {
      const msg = err?.message?.substring(0, 60) || '未知错误';
      aliyunResults.push(`#${i + 1}: 失败(${msg})`);
    }
  }

  // ---- Step 4: 等异步写入落库 ----
  console.log('\n⏳ 等待异步日志写入...');
  await new Promise(r => setTimeout(r, 3000));

  // ---- Step 5: 数据库验证 ----
  const afterCount = await prisma.aiCallLog.count();
  const newRecords = afterCount - beforeCount;
  
  const miniMaxDbCount = await prisma.aiCallLog.count({
    where: { callType: 'tts_test_create' }
  });
  const aliyunDbCount = await prisma.aiCallLog.count({
    where: { callType: 'tts_test_synthesize' }
  });
  const totalExpected = TEST_COUNT * 2; // MiniMax + 阿里云
  const totalActual = miniMaxDbCount + aliyunDbCount;

  console.log('\n╔══════════════════════════════════════════╗');
  console.log('║   📊 测试结果报告                        ║');
  console.log('╚══════════════════════════════════════════╝');
  console.log(`\n  发送请求总数:     ${totalExpected} (MiniMax ${TEST_COUNT} + 阿里云 ${TEST_COUNT})`);
  console.log(`  DB 新增记录:      ${newRecords}`);
  console.log(`  MiniMax 入库:     ${miniMaxDbCount} / ${TEST_COUNT}`);
  console.log(`  阿里云 入库:      ${aliyunDbCount} / ${TEST_COUNT}`);
  console.log(`  实际入库总数:     ${totalActual} / ${totalExpected}`);
  console.log(`  遗漏率:          ${totalExpected - totalActual > 0 ? ((totalExpected - totalActual) / totalExpected * 100).toFixed(1) + '%' : '0%'}`);

  // ---- 详细信息 ----
  const recentLogs = await prisma.aiCallLog.findMany({
    where: { callType: { in: ['tts_test_create', 'tts_test_synthesize'] } },
    orderBy: { createdAt: 'desc' },
    take: 5,
    select: { id: true, callType: true, provider: true, success: true, errorMsg: true, duration: true, createdAt: true }
  });
  
  console.log(`\n  最近 5 条测试日志:`);
  for (const log of recentLogs) {
    const status = log.success ? '✅' : '❌';
    const err = log.errorMsg ? ` (${log.errorMsg.substring(0, 40)})` : '';
    console.log(`    ${status} #${log.id} ${log.callType} | ${log.provider} | ${log.duration}ms${err}`);
  }

  // ---- Step 6: 检查是否有异常大量的历史 TTS 请求 ----
  const last24h = new Date(Date.now() - 24 * 60 * 60 * 1000);
  const last24hTtsCalls = await prisma.aiCallLog.count({
    where: {
      callType: { startsWith: 'tts' },
      createdAt: { gte: last24h },
    }
  });
  
  const ttsBreakdown = await prisma.aiCallLog.groupBy({
    by: ['callType', 'provider'],
    where: {
      callType: { startsWith: 'tts' },
      createdAt: { gte: last24h },
    },
    _count: { id: true },
  });
  ttsBreakdown.sort((a, b) => b._count.id - a._count.id);

  console.log(`\n\n╔══════════════════════════════════════════╗`);
  console.log(`║   📊 过去 24h TTS 请求统计              ║`);
  console.log(`╚══════════════════════════════════════════╝`);
  console.log(`\n  24h TTS 总请求数: ${last24hTtsCalls}`);
  console.log(`\n  按类型/供应商拆分:`);
  for (const item of ttsBreakdown.slice(0, 15)) {
    console.log(`    ${item.callType.padEnd(25)} | ${(item.provider || '-').padEnd(15)} | ${String(item._count.id).padStart(6)} 次`);
  }

  // ---- Step 7: 对比日志文件 ----
  let logFileCount = 0;
  try {
    if (fs.existsSync(LOG_FILE)) {
      const logContent = fs.readFileSync(LOG_FILE, 'utf-8');
      logFileCount = (logContent.match(/\[TTS\]/g) || []).length;
      console.log(`\n  tts-debug.log 文件中的 [TTS] 标记数: ${logFileCount}`);
    } else {
      console.log(`\n  ⚠️ tts-debug.log 文件不存在`);
    }
  } catch (e) {
    console.log(`\n  ⚠️ 无法读取 tts-debug.log: ${(e as Error).message}`);
  }

  // ---- 结论 ----
  console.log(`\n\n╔══════════════════════════════════════════╗`);
  console.log(`║   🎯 结论                                ║`);
  console.log(`╚══════════════════════════════════════════╝`);
  
  if (totalActual === totalExpected) {
    console.log(`  ✅ 日志记录完整：${totalActual}/${totalExpected} 全部入库，0%遗漏`);
  } else if (totalActual >= totalExpected * 0.9) {
    console.log(`  ⚠️ 轻微遗漏：${totalExpected - totalActual} 条未入库（${((1 - totalActual/totalExpected)*100).toFixed(1)}%）`);
  } else {
    console.log(`  ❌ 严重遗漏：${totalExpected - totalActual} 条未入库（${((1 - totalActual/totalExpected)*100).toFixed(1)}%）`);
  }

  if (last24hTtsCalls > 1000) {
    console.log(`  ⚠️ 过去24h有 ${last24hTtsCalls} 次TTS请求，次数可能异常偏高，请检查死循环`);
  } else {
    console.log(`  ✅ 过去24h TTS请求 ${last24hTtsCalls} 次，在正常范围内`);
  }

  // 清理
  await prisma.$disconnect();
}

main().catch(err => {
  console.error('脚本异常:', err);
  prisma.$disconnect().then(() => process.exit(1));
});
