/**
 * AdminDatabaseController 单元测试
 * 
 * 功能描述：
 * - 测试管理员数据库管理控制器的所有HTTP端点
 * - 验证请求参数处理和响应格式
 * - 测试权限验证和异常处理
 * 
 * 职责分离：
 * - HTTP层测试，不涉及业务逻辑实现
 * - Mock业务服务，专注控制器逻辑
 * - 验证请求响应的正确性
 * 
 * 最近修改：
 * - 2026-01-09: 功能新增 - 创建AdminDatabaseController单元测试 (修改者: moyin)
 * 
 * @author moyin
 * @version 1.0.0
 * @since 2026-01-09
 * @lastModified 2026-01-09
 */

import { Test, TestingModule } from '@nestjs/testing';
import { AdminDatabaseController } from './admin_database.controller';
import { DatabaseManagementService } from './database_management.service';
import { AdminOperationLogService } from './admin_operation_log.service';
import { AdminGuard } from './admin.guard';

describe('AdminDatabaseController', () => {
  let controller: AdminDatabaseController;
  let databaseService: jest.Mocked<DatabaseManagementService>;

  const mockDatabaseService = {
    // User management methods
    getUserList: jest.fn(),
    getUserById: jest.fn(),
    searchUsers: jest.fn(),
    createUser: jest.fn(),
    updateUser: jest.fn(),
    deleteUser: jest.fn(),
    
    // User profile management methods
    getUserProfileList: jest.fn(),
    getUserProfileById: jest.fn(),
    getUserProfilesByMap: jest.fn(),
    createUserProfile: jest.fn(),
    updateUserProfile: jest.fn(),
    deleteUserProfile: jest.fn(),
    
    // Zulip account management methods
    getZulipAccountList: jest.fn(),
    getZulipAccountById: jest.fn(),
    getZulipAccountStatistics: jest.fn(),
    createZulipAccount: jest.fn(),
    updateZulipAccount: jest.fn(),
    deleteZulipAccount: jest.fn(),
    batchUpdateZulipAccountStatus: jest.fn(),
  };

  const mockAdminOperationLogService = {
    createLog: jest.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [AdminDatabaseController],
      providers: [
        {
          provide: DatabaseManagementService,
          useValue: mockDatabaseService,
        },
        {
          provide: AdminOperationLogService,
          useValue: mockAdminOperationLogService,
        },
      ],
    })
      .overrideGuard(AdminGuard)
      .useValue({ canActivate: () => true })
      .compile();

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

  afterEach(() => {
    jest.clearAllMocks();
  });

  describe('User Management', () => {
    describe('getUserList', () => {
      it('should get user list with default pagination', async () => {
        const mockResponse = {
          success: true,
          data: { items: [], total: 0, limit: 20, offset: 0, has_more: false },
          message: '用户列表获取成功'
        };

        databaseService.getUserList.mockResolvedValue(mockResponse);

        const result = await controller.getUserList(20, 0);

        expect(databaseService.getUserList).toHaveBeenCalledWith(20, 0);
        expect(result).toEqual(mockResponse);
      });

      it('should get user list with custom pagination', async () => {
        const query = { limit: 50, offset: 10 };
        const mockResponse = {
          success: true,
          data: { items: [], total: 0, limit: 50, offset: 10, has_more: false },
          message: '用户列表获取成功'
        };

        databaseService.getUserList.mockResolvedValue(mockResponse);

        const result = await controller.getUserList(20, 0);

        expect(databaseService.getUserList).toHaveBeenCalledWith(20, 0);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('getUserById', () => {
      it('should get user by id successfully', async () => {
        const mockResponse = {
          success: true,
          data: { id: '1', username: 'testuser' },
          message: '用户详情获取成功'
        };

        databaseService.getUserById.mockResolvedValue(mockResponse);

        const result = await controller.getUserById('1');

        expect(databaseService.getUserById).toHaveBeenCalledWith(BigInt(1));
        expect(result).toEqual(mockResponse);
      });
    });

    describe('searchUsers', () => {
      it('should search users successfully', async () => {
        const query = { search: 'admin', limit: 10 };
        const mockResponse = {
          success: true,
          data: { items: [], total: 0, limit: 10, offset: 0, has_more: false },
          message: '用户搜索成功'
        };

        databaseService.searchUsers.mockResolvedValue(mockResponse);

        const result = await controller.searchUsers('admin', 20);

        expect(databaseService.searchUsers).toHaveBeenCalledWith('admin', 20);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('createUser', () => {
      it('should create user successfully', async () => {
        const userData = { username: 'newuser', nickname: 'New User', email: 'new@test.com' };
        const mockResponse = {
          success: true,
          data: { id: '1', ...userData },
          message: '用户创建成功'
        };

        databaseService.createUser.mockResolvedValue(mockResponse);

        const result = await controller.createUser(userData);

        expect(databaseService.createUser).toHaveBeenCalledWith(userData);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('updateUser', () => {
      it('should update user successfully', async () => {
        const updateData = { nickname: 'Updated User' };
        const mockResponse = {
          success: true,
          data: { id: '1', nickname: 'Updated User' },
          message: '用户更新成功'
        };

        databaseService.updateUser.mockResolvedValue(mockResponse);

        const result = await controller.updateUser('1', updateData);

        expect(databaseService.updateUser).toHaveBeenCalledWith(BigInt(1), updateData);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('deleteUser', () => {
      it('should delete user successfully', async () => {
        const mockResponse = {
          success: true,
          data: { deleted: true, id: '1' },
          message: '用户删除成功'
        };

        databaseService.deleteUser.mockResolvedValue(mockResponse);

        const result = await controller.deleteUser('1');

        expect(databaseService.deleteUser).toHaveBeenCalledWith(BigInt(1));
        expect(result).toEqual(mockResponse);
      });
    });
  });

  describe('User Profile Management', () => {
    describe('getUserProfileList', () => {
      it('should get user profile list successfully', async () => {
        const query = { limit: 20, offset: 0 };
        const mockResponse = {
          success: true,
          data: { items: [], total: 0, limit: 20, offset: 0, has_more: false },
          message: '用户档案列表获取成功'
        };

        databaseService.getUserProfileList.mockResolvedValue(mockResponse);

        const result = await controller.getUserProfileList(20, 0);

        expect(databaseService.getUserProfileList).toHaveBeenCalledWith(20, 0);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('getUserProfileById', () => {
      it('should get user profile by id successfully', async () => {
        const mockResponse = {
          success: true,
          data: { id: '1', user_id: '1', bio: 'Test bio' },
          message: '用户档案详情获取成功'
        };

        databaseService.getUserProfileById.mockResolvedValue(mockResponse);

        const result = await controller.getUserProfileById('1');

        expect(databaseService.getUserProfileById).toHaveBeenCalledWith(BigInt(1));
        expect(result).toEqual(mockResponse);
      });
    });

    describe('getUserProfilesByMap', () => {
      it('should get user profiles by map successfully', async () => {
        const mockResponse = {
          success: true,
          data: { items: [], total: 0, limit: 20, offset: 0, has_more: false },
          message: 'plaza 的用户档案列表获取成功'
        };

        databaseService.getUserProfilesByMap.mockResolvedValue(mockResponse);

        const result = await controller.getUserProfilesByMap('plaza', 20, 0);

        expect(databaseService.getUserProfilesByMap).toHaveBeenCalledWith('plaza', 20, 0);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('createUserProfile', () => {
      it('should create user profile successfully', async () => {
        const profileData = {
          user_id: '1',
          bio: 'Test bio',
          resume_content: 'Test resume',
          tags: '["tag1"]',
          social_links: '{"github":"test"}',
          skin_id: '1',
          current_map: 'plaza',
          pos_x: 100,
          pos_y: 200,
          status: 1
        };

        const mockResponse = {
          success: true,
          data: { id: '1', ...profileData },
          message: '用户档案创建成功'
        };

        databaseService.createUserProfile.mockResolvedValue(mockResponse);

        const result = await controller.createUserProfile(profileData);

        expect(databaseService.createUserProfile).toHaveBeenCalledWith(profileData);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('updateUserProfile', () => {
      it('should update user profile successfully', async () => {
        const updateData = { bio: 'Updated bio' };
        const mockResponse = {
          success: true,
          data: { id: '1', bio: 'Updated bio' },
          message: '用户档案更新成功'
        };

        databaseService.updateUserProfile.mockResolvedValue(mockResponse);

        const result = await controller.updateUserProfile('1', updateData);

        expect(databaseService.updateUserProfile).toHaveBeenCalledWith(BigInt(1), updateData);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('deleteUserProfile', () => {
      it('should delete user profile successfully', async () => {
        const mockResponse = {
          success: true,
          data: { deleted: true, id: '1' },
          message: '用户档案删除成功'
        };

        databaseService.deleteUserProfile.mockResolvedValue(mockResponse);

        const result = await controller.deleteUserProfile('1');

        expect(databaseService.deleteUserProfile).toHaveBeenCalledWith(BigInt(1));
        expect(result).toEqual(mockResponse);
      });
    });
  });

  describe('Zulip Account Management', () => {
    describe('getZulipAccountList', () => {
      it('should get zulip account list successfully', async () => {
        const query = { limit: 20, offset: 0 };
        const mockResponse = {
          success: true,
          data: { items: [], total: 0, limit: 20, offset: 0, has_more: false },
          message: 'Zulip账号关联列表获取成功'
        };

        databaseService.getZulipAccountList.mockResolvedValue(mockResponse);

        const result = await controller.getZulipAccountList(20, 0);

        expect(databaseService.getZulipAccountList).toHaveBeenCalledWith(20, 0);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('getZulipAccountById', () => {
      it('should get zulip account by id successfully', async () => {
        const mockResponse = {
          success: true,
          data: { id: '1', gameUserId: '1', zulipEmail: 'test@zulip.com' },
          message: 'Zulip账号关联详情获取成功'
        };

        databaseService.getZulipAccountById.mockResolvedValue(mockResponse);

        const result = await controller.getZulipAccountById('1');

        expect(databaseService.getZulipAccountById).toHaveBeenCalledWith('1');
        expect(result).toEqual(mockResponse);
      });
    });

    describe('getZulipAccountStatistics', () => {
      it('should get zulip account statistics successfully', async () => {
        const mockResponse = {
          success: true,
          data: { active: 10, inactive: 5, total: 15 },
          message: 'Zulip账号关联统计获取成功'
        };

        databaseService.getZulipAccountStatistics.mockResolvedValue(mockResponse);

        const result = await controller.getZulipAccountStatistics();

        expect(databaseService.getZulipAccountStatistics).toHaveBeenCalled();
        expect(result).toEqual(mockResponse);
      });
    });

    describe('createZulipAccount', () => {
      it('should create zulip account successfully', async () => {
        const accountData = {
          gameUserId: '1',
          zulipUserId: 123,
          zulipEmail: 'test@zulip.com',
          zulipFullName: 'Test User',
          zulipApiKeyEncrypted: 'encrypted_key'
        };

        const mockResponse = {
          success: true,
          data: { id: '1', ...accountData },
          message: 'Zulip账号关联创建成功'
        };

        databaseService.createZulipAccount.mockResolvedValue(mockResponse);

        const result = await controller.createZulipAccount(accountData);

        expect(databaseService.createZulipAccount).toHaveBeenCalledWith(accountData);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('updateZulipAccount', () => {
      it('should update zulip account successfully', async () => {
        const updateData = { zulipFullName: 'Updated Name' };
        const mockResponse = {
          success: true,
          data: { id: '1', zulipFullName: 'Updated Name' },
          message: 'Zulip账号关联更新成功'
        };

        databaseService.updateZulipAccount.mockResolvedValue(mockResponse);

        const result = await controller.updateZulipAccount('1', updateData);

        expect(databaseService.updateZulipAccount).toHaveBeenCalledWith('1', updateData);
        expect(result).toEqual(mockResponse);
      });
    });

    describe('deleteZulipAccount', () => {
      it('should delete zulip account successfully', async () => {
        const mockResponse = {
          success: true,
          data: { deleted: true, id: '1' },
          message: 'Zulip账号关联删除成功'
        };

        databaseService.deleteZulipAccount.mockResolvedValue(mockResponse);

        const result = await controller.deleteZulipAccount('1');

        expect(databaseService.deleteZulipAccount).toHaveBeenCalledWith('1');
        expect(result).toEqual(mockResponse);
      });
    });

    describe('batchUpdateZulipAccountStatus', () => {
      it('should batch update zulip account status successfully', async () => {
        const batchData = {
          ids: ['1', '2', '3'],
          status: 'active' as const,
          reason: 'Batch activation'
        };

        const mockResponse = {
          success: true,
          data: {
            success_count: 3,
            failed_count: 0,
            total_count: 3,
            reason: 'Batch activation'
          },
          message: 'Zulip账号关联批量状态更新完成，成功：3，失败：0'
        };

        databaseService.batchUpdateZulipAccountStatus.mockResolvedValue(mockResponse);

        const result = await controller.batchUpdateZulipAccountStatus(batchData);

        expect(databaseService.batchUpdateZulipAccountStatus).toHaveBeenCalledWith(
          ['1', '2', '3'],
          'active',
          'Batch activation'
        );
        expect(result).toEqual(mockResponse);
      });
    });
  });

  describe('Health Check', () => {
    describe('healthCheck', () => {
      it('should return health status successfully', async () => {
        const result = await controller.healthCheck();

        expect(result.success).toBe(true);
        expect(result.data.status).toBe('healthy');
        expect(result.data.services).toBeDefined();
        expect(result.data.services.users).toBe('connected');
        expect(result.data.services.user_profiles).toBe('connected');
        expect(result.data.services.zulip_accounts).toBe('connected');
        expect(result.message).toBe('数据库管理系统运行正常');
      });
    });
  });
});