/**
 * 容错测试 - 测试系统在异常情况下的处理能力
 */
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
import { VotingEngine, loadVotingScripts } from '../services/voting.engine';
import { adminService } from '../services/admin.service';
import { redis } from '../config/redis';

describe('容错测试', () => {
  let votingEngine: VotingEngine;

  beforeAll(async () => {
    await loadVotingScripts();
    votingEngine = new VotingEngine();
  });

  beforeEach(async () => {
    // 清理测试数据
    const keys = await redis.keys('vote:*test*');
    if (keys.length > 0) await redis.del(...keys);
    // 重置状态
    await adminService.setPhase('lottery');
    await adminService.controlLottery('reset');
  });

  describe('投票容错', () => {
    it('无效票种应该返回错误', async () => {
      const result = await votingEngine.castVote(
        'test_user',
        'test_program',
        'invalid_ticket_type' as any
      );
      expect(result.success).toBe(false);
      expect(result.error).toBe('INVALID_TICKET_TYPE');
    });

    it('空用户ID应该被处理', async () => {
      const result = await votingEngine.castVote(
        '',
        'test_program',
        'creative'
      );
      // 系统应该能处理空用户ID（可能成功或返回错误）
      expect(result).toBeDefined();
    });

    it('空节目ID应该被处理', async () => {
      const result = await votingEngine.castVote(
        'test_user',
        '',
        'creative'
      );
      expect(result).toBeDefined();
    });
  });

  describe('抽奖状态容错', () => {
    it('未开始银河阶段直接进入风暴应该失败', async () => {
      const result = await adminService.controlLottery('start_storm');
      expect(result.success).toBe(false);
      expect(result.message).toContain('GALAXY');
    });

    it('未进入风暴阶段直接揭晓应该失败', async () => {
      await adminService.controlLottery('start_galaxy');
      const result = await adminService.controlLottery('stop_reveal');
      expect(result.success).toBe(false);
      expect(result.message).toContain('STORM');
    });

    it('重复开始银河阶段应该失败', async () => {
      await adminService.controlLottery('start_galaxy');
      const result = await adminService.controlLottery('start_galaxy');
      expect(result.success).toBe(false);
    });

    it('未完成当前轮次直接下一轮应该失败', async () => {
      await adminService.controlLottery('start_galaxy');
      const result = await adminService.controlLottery('next_round');
      expect(result.success).toBe(false);
    });
  });

  describe('投票控制容错', () => {
    it('重复开启投票应该返回错误', async () => {
      await adminService.setPhase('voting');
      await adminService.controlVoting('open');
      const result = await adminService.controlVoting('open');
      expect(result.success).toBe(false);
      expect(result.message).toContain('already');
    });

    it('重复关闭投票应该返回错误', async () => {
      await adminService.setPhase('voting');
      await adminService.controlVoting('close');
      const result = await adminService.controlVoting('close');
      expect(result.success).toBe(false);
      expect(result.message).toContain('already');
    });

    it('未开启投票时暂停应该失败', async () => {
      await adminService.setPhase('voting');
      await adminService.controlVoting('close');
      const result = await adminService.controlVoting('pause');
      expect(result.success).toBe(false);
    });

    it('未暂停时恢复应该失败', async () => {
      await adminService.setPhase('voting');
      await adminService.controlVoting('open');
      const result = await adminService.controlVoting('resume');
      expect(result.success).toBe(false);
    });
  });

  describe('边界条件', () => {
    it('超长用户ID应该被处理', async () => {
      const longUserId = 'u'.repeat(1000);
      const result = await votingEngine.castVote(
        longUserId,
        'test_program',
        'creative'
      );
      expect(result).toBeDefined();
    });

    it('特殊字符用户ID应该被处理', async () => {
      const result = await votingEngine.castVote(
        'user<script>alert(1)</script>',
        'test_program',
        'creative'
      );
      expect(result).toBeDefined();
    });

    it('Unicode用户ID应该被处理', async () => {
      const result = await votingEngine.castVote(
        '测试用户🎉',
        'test_program',
        'creative'
      );
      expect(result).toBeDefined();
    });
  });
});
