/**
 * 管理员数据库管理集成测试
 * 
 * 功能描述：
 * - 测试管理员数据库管理的完整功能
 * - 验证CRUD操作的正确性
 * - 测试权限控制和错误处理
 * - 验证响应格式的一致性
 * 
 * 测试覆盖：
 * - 用户管理功能测试
 * - 用户档案管理功能测试
 * - Zulip账号关联管理功能测试
 * - 批量操作功能测试
 * - 错误处理和边界条件测试
 * 
 * 最近修改：
 * - 2026-01-08: 注释规范优化 - 修正@author字段，更新版本号和修改记录 (修改者: moyin)
 * - 2026-01-08: 功能新增 - 创建管理员数据库管理集成测试 (修改者: assistant)
 * 
 * @author moyin
 * @version 1.0.1
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AdminDatabaseController } from './admin_database.controller';
import { DatabaseManagementService } from './database_management.service';
import { AdminOperationLogService } from './admin_operation_log.service';
import { AdminOperationLogInterceptor } from './admin_operation_log.interceptor';
import { AdminDatabaseExceptionFilter } from './admin_database_exception.filter';
import { AdminGuard } from './admin.guard';
import { UserStatus } from '../user_mgmt/user_status.enum';

describe('Admin Database Management Integration Tests', () => {
  let app: INestApplication;
  let module: TestingModule;
  let controller: AdminDatabaseController;
  let service: DatabaseManagementService;

  // 测试数据
  const testUser = {
    username: 'admin-test-user',
    nickname: '管理员测试用户',
    email: 'admin-test@example.com',
    role: 1,
    status: UserStatus.ACTIVE
  };

  const testProfile = {
    user_id: '1',
    bio: '管理员测试档案',
    current_map: 'test-plaza',
    pos_x: 100.5,
    pos_y: 200.3,
    status: 1
  };

  const testZulipAccount = {
    gameUserId: '1',
    zulipUserId: 12345,
    zulipEmail: 'test@zulip.com',
    zulipFullName: '测试用户',
    zulipApiKeyEncrypted: 'encrypted_test_key',
    status: 'active' as const
  };

  beforeAll(async () => {
    module = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          envFilePath: ['.env.test', '.env']
        })
      ],
      controllers: [AdminDatabaseController],
      providers: [
        DatabaseManagementService,
        // Mock AdminOperationLogService for testing
        {
          provide: AdminOperationLogService,
          useValue: {
            createLog: jest.fn().mockResolvedValue({}),
            queryLogs: jest.fn().mockResolvedValue({ logs: [], total: 0 }),
            getLogById: jest.fn().mockResolvedValue(null),
            getStatistics: jest.fn().mockResolvedValue({}),
            cleanupExpiredLogs: jest.fn().mockResolvedValue(0),
            getAdminOperationHistory: jest.fn().mockResolvedValue([]),
            getSensitiveOperations: jest.fn().mockResolvedValue({ logs: [], total: 0 })
          }
        },
        // Mock AdminOperationLogInterceptor
        {
          provide: AdminOperationLogInterceptor,
          useValue: {
            intercept: jest.fn().mockImplementation((context, next) => next.handle())
          }
        },
        {
          provide: 'UsersService',
          useValue: {
            findAll: jest.fn().mockResolvedValue([]),
            findOne: jest.fn().mockResolvedValue({ ...testUser, id: BigInt(1) }),
            create: jest.fn().mockResolvedValue({ ...testUser, id: BigInt(1) }),
            update: jest.fn().mockResolvedValue({ ...testUser, id: BigInt(1) }),
            remove: jest.fn().mockResolvedValue(undefined),
            search: jest.fn().mockResolvedValue([]),
            count: jest.fn().mockResolvedValue(0)
          }
        },
        {
          provide: 'IUserProfilesService',
          useValue: {
            findAll: jest.fn().mockResolvedValue([]),
            findOne: jest.fn().mockResolvedValue({ ...testProfile, id: BigInt(1) }),
            create: jest.fn().mockResolvedValue({ ...testProfile, id: BigInt(1) }),
            update: jest.fn().mockResolvedValue({ ...testProfile, id: BigInt(1) }),
            remove: jest.fn().mockResolvedValue(undefined),
            findByMap: jest.fn().mockResolvedValue([]),
            count: jest.fn().mockResolvedValue(0)
          }
        },
        {
          provide: 'ZulipAccountsService',
          useValue: {
            findMany: jest.fn().mockResolvedValue({ accounts: [] }),
            findById: jest.fn().mockResolvedValue(testZulipAccount),
            create: jest.fn().mockResolvedValue({ ...testZulipAccount, id: '1' }),
            update: jest.fn().mockResolvedValue({ ...testZulipAccount, id: '1' }),
            delete: jest.fn().mockResolvedValue(undefined),
            getStatusStatistics: jest.fn().mockResolvedValue({
              active: 0,
              inactive: 0,
              suspended: 0,
              error: 0,
              total: 0
            })
          }
        }
      ]
    })
    .overrideGuard(AdminGuard)
    .useValue({ canActivate: () => true })
    .compile();

    app = module.createNestApplication();
    app.useGlobalFilters(new AdminDatabaseExceptionFilter());
    await app.init();

    controller = module.get<AdminDatabaseController>(AdminDatabaseController);
    service = module.get<DatabaseManagementService>(DatabaseManagementService);
  });

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

  describe('用户管理功能测试', () => {
    it('应该成功获取用户列表', async () => {
      const result = await controller.getUserList(20, 0);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.items).toBeInstanceOf(Array);
      expect(result.data.total).toBeDefined();
      expect(result.data.limit).toBe(20);
      expect(result.data.offset).toBe(0);
      expect(result.message).toBe('用户列表获取成功');
    });

    it('应该成功获取用户详情', async () => {
      const result = await controller.getUserById('1');
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.username).toBe(testUser.username);
      expect(result.message).toBe('用户详情获取成功');
    });

    it('应该成功创建用户', async () => {
      const result = await controller.createUser(testUser);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.username).toBe(testUser.username);
      expect(result.message).toBe('用户创建成功');
    });

    it('应该成功更新用户', async () => {
      const updateData = { nickname: '更新后的昵称' };
      const result = await controller.updateUser('1', updateData);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.message).toBe('用户更新成功');
    });

    it('应该成功删除用户', async () => {
      const result = await controller.deleteUser('1');
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data.deleted).toBe(true);
      expect(result.message).toBe('用户删除成功');
    });

    it('应该成功搜索用户', async () => {
      const result = await controller.searchUsers('admin', 20);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.items).toBeInstanceOf(Array);
      expect(result.message).toBe('用户搜索成功');
    });
  });

  describe('用户档案管理功能测试', () => {
    it('应该成功获取用户档案列表', async () => {
      const result = await controller.getUserProfileList(20, 0);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.items).toBeInstanceOf(Array);
      expect(result.message).toBe('用户档案列表获取成功');
    });

    it('应该成功获取用户档案详情', async () => {
      const result = await controller.getUserProfileById('1');
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.user_id).toBe(testProfile.user_id);
      expect(result.message).toBe('用户档案详情获取成功');
    });

    it('应该成功创建用户档案', async () => {
      const result = await controller.createUserProfile(testProfile);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.user_id).toBe(testProfile.user_id);
      expect(result.message).toBe('用户档案创建成功');
    });

    it('应该成功更新用户档案', async () => {
      const updateData = { bio: '更新后的简介' };
      const result = await controller.updateUserProfile('1', updateData);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.message).toBe('用户档案更新成功');
    });

    it('应该成功删除用户档案', async () => {
      const result = await controller.deleteUserProfile('1');
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data.deleted).toBe(true);
      expect(result.message).toBe('用户档案删除成功');
    });

    it('应该成功根据地图获取用户档案', async () => {
      const result = await controller.getUserProfilesByMap('plaza', 20, 0);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.items).toBeInstanceOf(Array);
      expect(result.message).toBe('地图 plaza 的用户档案获取成功');
    });
  });

  describe('Zulip账号关联管理功能测试', () => {
    it('应该成功获取Zulip账号关联列表', async () => {
      const result = await controller.getZulipAccountList(20, 0);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.items).toBeInstanceOf(Array);
      expect(result.message).toBe('Zulip账号关联列表获取成功');
    });

    it('应该成功获取Zulip账号关联详情', async () => {
      const result = await controller.getZulipAccountById('1');
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.gameUserId).toBe(testZulipAccount.gameUserId);
      expect(result.message).toBe('Zulip账号关联详情获取成功');
    });

    it('应该成功创建Zulip账号关联', async () => {
      const result = await controller.createZulipAccount(testZulipAccount);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.gameUserId).toBe(testZulipAccount.gameUserId);
      expect(result.message).toBe('Zulip账号关联创建成功');
    });

    it('应该成功更新Zulip账号关联', async () => {
      const updateData = { status: 'inactive' as const };
      const result = await controller.updateZulipAccount('1', updateData);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.message).toBe('Zulip账号关联更新成功');
    });

    it('应该成功删除Zulip账号关联', async () => {
      const result = await controller.deleteZulipAccount('1');
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data.deleted).toBe(true);
      expect(result.message).toBe('Zulip账号关联删除成功');
    });

    it('应该成功批量更新Zulip账号状态', async () => {
      const batchData = {
        ids: ['1', '2', '3'],
        status: 'active' as 'active' | 'inactive' | 'suspended' | 'error',
        reason: '批量激活测试'
      };
      const result = await controller.batchUpdateZulipAccountStatus(batchData);
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.total).toBe(3);
      expect(result.message).toContain('批量更新完成');
    });

    it('应该成功获取Zulip账号关联统计', async () => {
      const result = await controller.getZulipAccountStatistics();
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.total).toBeDefined();
      expect(result.message).toBe('Zulip账号关联统计获取成功');
    });
  });

  describe('系统功能测试', () => {
    it('应该成功进行健康检查', async () => {
      const result = await controller.healthCheck();
      
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
      expect(result.data).toBeDefined();
      expect(result.data.status).toBe('healthy');
      expect(result.data.services).toBeDefined();
      expect(result.message).toBe('数据库管理系统运行正常');
    });
  });

  describe('响应格式一致性测试', () => {
    it('所有成功响应应该有统一的格式', async () => {
      const responses = [
        await controller.getUserList(20, 0),
        await controller.getUserById('1'),
        await controller.getUserProfileList(20, 0),
        await controller.getZulipAccountList(20, 0),
        await controller.healthCheck()
      ];

      responses.forEach(response => {
        expect(response).toHaveProperty('success');
        expect(response).toHaveProperty('message');
        expect(response).toHaveProperty('data');
        expect(response).toHaveProperty('timestamp');
        expect(response).toHaveProperty('request_id');
        expect(response.success).toBe(true);
        expect(typeof response.message).toBe('string');
        expect(typeof response.timestamp).toBe('string');
        expect(typeof response.request_id).toBe('string');
      });
    });

    it('列表响应应该有分页信息', async () => {
      const listResponses = [
        await controller.getUserList(20, 0),
        await controller.getUserProfileList(20, 0),
        await controller.getZulipAccountList(20, 0)
      ];

      listResponses.forEach(response => {
        expect(response.data).toHaveProperty('items');
        expect(response.data).toHaveProperty('total');
        expect(response.data).toHaveProperty('limit');
        expect(response.data).toHaveProperty('offset');
        expect(response.data).toHaveProperty('has_more');
        expect(Array.isArray(response.data.items)).toBe(true);
        expect(typeof response.data.total).toBe('number');
        expect(typeof response.data.limit).toBe('number');
        expect(typeof response.data.offset).toBe('number');
        expect(typeof response.data.has_more).toBe('boolean');
      });
    });
  });

  describe('参数验证测试', () => {
    it('应该正确处理分页参数限制', async () => {
      // 测试超过最大限制的情况
      const result = await controller.getUserList(200, 0);
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
    });

    it('应该正确处理搜索参数限制', async () => {
      const result = await controller.searchUsers('test', 100);
      expect(result).toBeDefined();
      expect(result.success).toBe(true);
    });
  });
});