/**
 * Zulip账号关联服务数据库测试
 * 
 * 功能描述：
 * - 专门测试数据库模式下的真实数据库操作
 * - 需要配置数据库环境变量才能运行
 * - 测试真实的CRUD操作和业务逻辑
 * 
 * 运行条件：
 * - 需要设置环境变量：DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_NAME
 * - 数据库中需要存在 zulip_accounts 表
 * 
 * @author angjustinl
 * @version 1.0.0
 * @since 2026-01-10
 */

import { Test, TestingModule } from '@nestjs/testing';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';
import { CacheModule } from '@nestjs/cache-manager';
import { ZulipAccountsService } from '../../src/core/db/zulip_accounts/zulip_accounts.service';
import { ZulipAccountsRepository } from '../../src/core/db/zulip_accounts/zulip_accounts.repository';
import { ZulipAccounts } from '../../src/core/db/zulip_accounts/zulip_accounts.entity';
import { Users } from '../../src/core/db/users/users.entity';
import { AppLoggerService } from '../../src/core/utils/logger/logger.service';

/**
 * 检查是否配置了数据库
 */
function isDatabaseConfigured(): boolean {
  const requiredEnvVars = ['DB_HOST', 'DB_PORT', 'DB_USERNAME', 'DB_PASSWORD', 'DB_NAME'];
  return requiredEnvVars.every(varName => process.env[varName]);
}

// 只有在配置了数据库时才运行这些测试
const describeDatabase = isDatabaseConfigured() ? describe : describe.skip;

describeDatabase('ZulipAccountsService - Database Mode', () => {
  let service: ZulipAccountsService;
  let module: TestingModule;

  // 只有在数据库配置完整时才输出这些信息
  if (isDatabaseConfigured()) {
    console.log('🗄️ 运行数据库模式测试');
    console.log('📊 使用真实数据库连接进行测试');
  }

  beforeAll(async () => {
    module = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          envFilePath: ['.env.test', '.env'],
          isGlobal: true,
        }),
        TypeOrmModule.forRoot({
          type: 'mysql',
          host: process.env.DB_HOST,
          port: parseInt(process.env.DB_PORT || '3306'),
          username: process.env.DB_USERNAME,
          password: process.env.DB_PASSWORD,
          database: process.env.DB_NAME,
          entities: [ZulipAccounts, Users],
          synchronize: false,
          logging: false,
        }),
        TypeOrmModule.forFeature([ZulipAccounts, Users]),
        CacheModule.register({
          ttl: 300,
          max: 1000,
        }),
      ],
      providers: [
        ZulipAccountsService,
        ZulipAccountsRepository,
        AppLoggerService,
      ],
    }).compile();

    service = module.get<ZulipAccountsService>(ZulipAccountsService);
  }, 30000); // 增加超时时间

  afterAll(async () => {
    if (module) {
      await module.close();
    }
  });

  // 生成唯一的测试数据
  const generateTestData = (suffix: string = Date.now().toString()) => {
    const timestamp = Date.now();
    const uniqueId = timestamp + Math.floor(Math.random() * 1000); // 添加随机数避免冲突
    return {
      gameUserId: uniqueId.toString(), // 使用纯数字字符串
      zulipUserId: parseInt(`8${timestamp.toString().slice(-5)}`),
      zulipEmail: `test_db_${timestamp}_${suffix}@example.com`,
      zulipFullName: `数据库测试用户_${timestamp}_${suffix}`,
      zulipApiKeyEncrypted: 'encrypted_api_key_for_db_test',
      status: 'active' as const,
    };
  };

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('Database CRUD Operations', () => {
    it('should create and retrieve account from database', async () => {
      const testData = generateTestData('crud');
      
      // 创建账号
      const created = await service.create(testData);
      expect(created).toBeDefined();
      expect(created.gameUserId).toBe(testData.gameUserId);
      expect(created.zulipEmail).toBe(testData.zulipEmail);
      expect(created.status).toBe('active');

      // 根据游戏用户ID查找
      const found = await service.findByGameUserId(testData.gameUserId);
      expect(found).toBeDefined();
      expect(found?.id).toBe(created.id);
      expect(found?.zulipUserId).toBe(testData.zulipUserId);

      // 清理测试数据
      await service.deleteByGameUserId(testData.gameUserId);
    }, 15000);

    it('should handle duplicate creation properly', async () => {
      const testData = generateTestData('duplicate');
      
      // 创建第一个账号
      const created = await service.create(testData);
      expect(created).toBeDefined();

      // 尝试创建重复账号，应该抛出异常
      await expect(service.create(testData)).rejects.toThrow();

      // 清理测试数据
      await service.deleteByGameUserId(testData.gameUserId);
    }, 15000);

    it('should update account in database', async () => {
      const testData = generateTestData('update');
      
      // 创建账号
      const created = await service.create(testData);
      
      // 更新账号
      const updated = await service.update(created.id, {
        zulipFullName: '更新后的用户名',
        status: 'inactive',
      });

      expect(updated.zulipFullName).toBe('更新后的用户名');
      expect(updated.status).toBe('inactive');

      // 清理测试数据
      await service.deleteByGameUserId(testData.gameUserId);
    }, 15000);

    it('should delete account from database', async () => {
      const testData = generateTestData('delete');
      
      // 创建账号
      const created = await service.create(testData);
      
      // 删除账号
      const deleted = await service.delete(created.id);
      expect(deleted).toBe(true);

      // 验证账号已被删除
      const found = await service.findByGameUserId(testData.gameUserId);
      expect(found).toBeNull();
    }, 15000);
  });

  describe('Database Business Logic', () => {
    it('should check email existence in database', async () => {
      const testData = generateTestData('email_check');
      
      // 邮箱不存在时应该返回false
      const notExists = await service.existsByEmail(testData.zulipEmail);
      expect(notExists).toBe(false);

      // 创建账号
      await service.create(testData);

      // 邮箱存在时应该返回true
      const exists = await service.existsByEmail(testData.zulipEmail);
      expect(exists).toBe(true);

      // 清理测试数据
      await service.deleteByGameUserId(testData.gameUserId);
    }, 15000);

    it('should get status statistics from database', async () => {
      const stats = await service.getStatusStatistics();

      expect(typeof stats.active).toBe('number');
      expect(typeof stats.inactive).toBe('number');
      expect(typeof stats.suspended).toBe('number');
      expect(typeof stats.error).toBe('number');
      expect(typeof stats.total).toBe('number');
      expect(stats.total).toBe(stats.active + stats.inactive + stats.suspended + stats.error);
    }, 15000);

    it('should verify account in database', async () => {
      const testData = generateTestData('verify');
      
      // 创建账号
      await service.create(testData);

      // 验证账号
      const result = await service.verifyAccount(testData.gameUserId);
      expect(result.success).toBe(true);
      expect(result.isValid).toBe(true);
      expect(result.verifiedAt).toBeDefined();

      // 清理测试数据
      await service.deleteByGameUserId(testData.gameUserId);
    }, 15000);
  });
});

// 如果没有配置数据库，显示跳过信息
if (!isDatabaseConfigured()) {
  console.log('⚠️  数据库测试已跳过：未检测到数据库配置');
  console.log('💡 要运行数据库测试，请设置以下环境变量：');
  console.log('   - DB_HOST');
  console.log('   - DB_PORT');
  console.log('   - DB_USERNAME');
  console.log('   - DB_PASSWORD');
  console.log('   - DB_NAME');
}