/**
 * TTS 流程集成测试
 * 测试合成→存储→配额扣除完整流程
 */

import { describe, it, expect, beforeAll } from 'vitest';
import { apiPost, apiGet, setAuthToken, initHttpClient, createTestUser } from '../../integration/http-client';

describe('TTS 流程集成测试', () => {
  let authToken: string;
  let userId: string;
  let audioId: string;

  beforeAll(async () => {
    try {
      const user = await createTestUser();
      authToken = user.token;
      userId = user.userId;
      setAuthToken(authToken);
    } catch (e) {
      console.log('创建测试用户失败，跳过部分测试');
    }
  });

  describe('Step 1: 音色和提供商', () => {
    it('获取音色列表', async () => {
      if (!authToken) return;

      const res = await apiGet('/api/tts/voices');
      expect(res.code).toBe(0);
      expect(res.data?.voices).toBeDefined();
      expect(Array.isArray(res.data.voices)).toBe(true);
      expect(res.data.voices.length).toBeGreaterThan(0);
    });

    it('获取提供商列表', async () => {
      if (!authToken) return;

      const res = await apiGet('/api/tts/providers');
      expect(res.code).toBe(0);
      expect(res.data?.providers).toBeDefined();
    });

    it('获取用户可用配额', async () => {
      if (!authToken) return;

      const res = await apiGet('/api/auth/user-info');
      expect(res.code).toBe(0);
      // 检查每日配额字段存在
      expect(res.data).toHaveProperty('dailyUsage');
    });
  });

  describe('Step 2: TTS 音频生成', () => {
    it('生成 TTS 音频任务成功', async () => {
      if (!authToken) return;

      const res = await apiPost('/api/tts/generate', {
        text: '这是一段自动化测试文本，用于验证TTS音频生成功能。人工智能正在改变我们的生活方式。',
        voiceId: 'Cherry',
        voiceParams: {
          speed: 1.0,
          pitch: 0,
          volume: 50,
        },
      });

      expect(res.code).toBe(0);
      expect(res.data?.audioId).toBeDefined();
      audioId = res.data?.audioId;
    });

    it('无效音色返回错误', async () => {
      if (!authToken) return;

      const res = await apiPost('/api/tts/generate', {
        text: '测试文本',
        voiceId: 'InvalidVoiceName',
      });

      // 应该返回错误
      expect(res.code).not.toBe(0);
    });

    it('空文本返回错误', async () => {
      if (!authToken) return;

      const res = await apiPost('/api/tts/generate', {
        text: '',
        voiceId: 'Cherry',
      });

      expect(res.code).not.toBe(0);
    });
  });

  describe('Step 3: 查询音频状态', () => {
    it('查询刚生成的音频状态', async () => {
      if (!authToken || !audioId) return;

      const res = await apiGet(`/api/tts/status/${audioId}`);
      // 刚生成的音频查询请求应成功返回
      expect(res.code).toBeDefined();
      expect([401, 403]).not.toContain(res.code); // 不应该是认证/权限错误
    });

    it('查询不存在的音频返回错误', async () => {
      if (!authToken) return;

      const res = await apiGet('/api/tts/status/nonexistent_audio_id');
      // 不存在的音频应返回错误（404 或业务错误码）
      expect(res.code).not.toBe(0);
    });
  });

  describe('Step 4: 配额消耗验证', () => {
    it('生成音频后配额已使用', async () => {
      if (!authToken || !audioId) return;

      // 先获取用户信息记录当前使用量
      const userBefore = await apiGet('/api/auth/user-info');
      const usageBefore = userBefore.data?.dailyUsage || 0;

      // 生成新音频
      const genRes = await apiPost('/api/tts/generate', {
        text: '测试配额消耗',
        voiceId: 'Cherry',
      });

      // 如果生成成功，配额应该增加
      if (genRes.code === 0) {
        const userAfter = await apiGet('/api/auth/user-info');
        const usageAfter = userAfter.data?.dailyUsage || 0;
        // 配额应该增加了（或者已达上限）
        expect(usageAfter).toBeGreaterThanOrEqual(usageBefore);
      }
    });

    it('超额使用时返回配额不足错误', async () => {
      if (!authToken) return;

      // 尝试生成超长文本（超出免费配额）
      const res = await apiPost('/api/tts/generate', {
        text: 'A'.repeat(50000), // 超长文本
        voiceId: 'Cherry',
      });

      // 可能是配额不足或直接生成（取决于实现）
      // 免费用户可能有不同处理逻辑
      expect(res.code).toBeDefined();
    });
  });

  describe('Step 5: 音频下载', () => {
    it('获取下载信息', async () => {
      if (!authToken || !audioId) return;

      const res = await apiGet(`/api/tts/download/${audioId}`);
      // 音频可能尚未生成完毕(处理中)或已可下载
      expect(res.code).toBeDefined();
      expect([401, 403]).not.toContain(res.code);
    });
  });
});