/**
 * 分页查询属性测试
 * 
 * Property 8: 分页查询正确性
 * Property 14: 分页限制保护
 * 
 * Validates: Requirements 4.4, 4.5, 8.3
 * 
 * 测试目标：
 * - 验证分页查询的正确性和一致性
 * - 确保分页限制保护机制有效
 * - 验证分页参数的边界处理
 * 
 * 最近修改：
 * - 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 { 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';
import {
  PropertyTestRunner,
  PropertyTestGenerators,
  PropertyTestAssertions,
  DEFAULT_PROPERTY_CONFIG
} from './admin_property_test.base';

describe('Property Test: 分页查询功能', () => {
  let app: INestApplication;
  let module: TestingModule;
  let controller: AdminDatabaseController;
  let mockUsersService: any;
  let mockUserProfilesService: any;
  let mockZulipAccountsService: any;

  beforeAll(async () => {
    mockUsersService = {
      findAll: jest.fn(),
      findOne: jest.fn(),
      create: jest.fn(),
      update: jest.fn(),
      remove: jest.fn(),
      search: jest.fn(),
      count: jest.fn()
    };

    mockUserProfilesService = {
      findAll: jest.fn(),
      findOne: jest.fn(),
      create: jest.fn(),
      update: jest.fn(),
      remove: jest.fn(),
      findByMap: jest.fn(),
      count: jest.fn()
    };

    mockZulipAccountsService = {
      findMany: jest.fn(),
      findById: jest.fn(),
      create: jest.fn(),
      update: jest.fn(),
      delete: jest.fn(),
      batchUpdateStatus: jest.fn().mockResolvedValue({ success: true, updatedCount: 0 }),
      getStatusStatistics: jest.fn()
    };

    module = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          envFilePath: ['.env.test', '.env']
        })
      ],
      controllers: [AdminDatabaseController],
      providers: [
        DatabaseManagementService,
        {
          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 })
          }
        },
        {
          provide: AdminOperationLogInterceptor,
          useValue: {
            intercept: jest.fn().mockImplementation((context, next) => next.handle())
          }
        },
        {
          provide: 'UsersService',
          useValue: mockUsersService
        },
        {
          provide: 'IUserProfilesService',
          useValue: mockUserProfilesService
        },
        {
          provide: 'ZulipAccountsService',
          useValue: mockZulipAccountsService
        }
      ]
    })
    .overrideGuard(AdminGuard)
    .useValue({ canActivate: () => true })
    .compile();

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

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

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

  describe('Property 8: 分页查询正确性', () => {
    it('分页参数应该被正确传递和处理', async () => {
      await PropertyTestRunner.runPropertyTest(
        '分页参数传递正确性',
        () => PropertyTestGenerators.generatePaginationParams(),
        async (params) => {
          const { limit, offset } = params;
          const safeLimit = Math.min(Math.max(limit, 1), 100);
          const safeOffset = Math.max(offset, 0);
          
          const totalItems = Math.floor(Math.random() * 200) + 50;
          const itemsToReturn = Math.min(safeLimit, Math.max(0, totalItems - safeOffset));
          
          // Mock用户列表查询
          const mockUsers = Array.from({ length: itemsToReturn }, (_, i) => ({
            ...PropertyTestGenerators.generateUser(),
            id: BigInt(safeOffset + i + 1)
          }));
          
          mockUsersService.findAll.mockResolvedValueOnce(mockUsers);
          mockUsersService.count.mockResolvedValueOnce(totalItems);

          const response = await controller.getUserList(safeLimit, safeOffset);

          expect(response.success).toBe(true);
          PropertyTestAssertions.assertPaginationLogic(response, safeLimit, safeOffset);
          
          // 验证分页计算正确性
          expect(response.data.limit).toBe(safeLimit);
          expect(response.data.offset).toBe(safeOffset);
          expect(response.data.total).toBe(totalItems);
          expect(response.data.items.length).toBe(itemsToReturn);
          
          const expectedHasMore = safeOffset + itemsToReturn < totalItems;
          expect(response.data.has_more).toBe(expectedHasMore);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 50 }
      );
    });

    it('不同实体类型的分页查询应该保持一致性', async () => {
      await PropertyTestRunner.runPropertyTest(
        '多实体分页一致性',
        () => PropertyTestGenerators.generatePaginationParams(),
        async (params) => {
          const { limit, offset } = params;
          const safeLimit = Math.min(Math.max(limit, 1), 100);
          const safeOffset = Math.max(offset, 0);
          
          const totalCount = Math.floor(Math.random() * 100) + 20;
          const itemCount = Math.min(safeLimit, Math.max(0, totalCount - safeOffset));
          
          // Mock所有实体类型的查询
          mockUsersService.findAll.mockResolvedValueOnce(
            Array.from({ length: itemCount }, () => PropertyTestGenerators.generateUser())
          );
          mockUsersService.count.mockResolvedValueOnce(totalCount);
          
          mockUserProfilesService.findAll.mockResolvedValueOnce(
            Array.from({ length: itemCount }, () => PropertyTestGenerators.generateUserProfile())
          );
          mockUserProfilesService.count.mockResolvedValueOnce(totalCount);
          
          mockZulipAccountsService.findMany.mockResolvedValueOnce({
            accounts: Array.from({ length: itemCount }, () => PropertyTestGenerators.generateZulipAccount()),
            total: totalCount
          });

          // 测试所有列表端点
          const userResponse = await controller.getUserList(safeLimit, safeOffset);
          const profileResponse = await controller.getUserProfileList(safeLimit, safeOffset);
          const zulipResponse = await controller.getZulipAccountList(safeLimit, safeOffset);

          // 验证所有响应的分页格式一致
          [userResponse, profileResponse, zulipResponse].forEach(response => {
            PropertyTestAssertions.assertPaginationLogic(response, safeLimit, safeOffset);
            expect(response.data.limit).toBe(safeLimit);
            expect(response.data.offset).toBe(safeOffset);
          });
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 30 }
      );
    });

    it('边界条件下的分页查询应该正确处理', async () => {
      const boundaryValues = PropertyTestGenerators.generateBoundaryValues();
      
      await PropertyTestRunner.runPropertyTest(
        '分页边界条件处理',
        () => {
          const limits = boundaryValues.limits;
          const offsets = boundaryValues.offsets;
          
          return {
            limit: limits[Math.floor(Math.random() * limits.length)],
            offset: offsets[Math.floor(Math.random() * offsets.length)]
          };
        },
        async ({ limit, offset }) => {
          const safeLimit = Math.min(Math.max(limit, 1), 100);
          const safeOffset = Math.max(offset, 0);
          
          const totalItems = 150;
          const itemsToReturn = Math.min(safeLimit, Math.max(0, totalItems - safeOffset));
          
          mockUsersService.findAll.mockResolvedValueOnce(
            Array.from({ length: itemsToReturn }, () => PropertyTestGenerators.generateUser())
          );
          mockUsersService.count.mockResolvedValueOnce(totalItems);

          const response = await controller.getUserList(limit, offset);

          expect(response.success).toBe(true);
          
          // 验证边界值被正确处理
          expect(response.data.limit).toBeGreaterThan(0);
          expect(response.data.limit).toBeLessThanOrEqual(100);
          expect(response.data.offset).toBeGreaterThanOrEqual(0);
          expect(response.data.items.length).toBeLessThanOrEqual(response.data.limit);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 40 }
      );
    });

    it('空结果集的分页查询应该正确处理', async () => {
      await PropertyTestRunner.runPropertyTest(
        '空结果集分页处理',
        () => PropertyTestGenerators.generatePaginationParams(),
        async (params) => {
          const { limit, offset } = params;
          const safeLimit = Math.min(Math.max(limit, 1), 100);
          const safeOffset = Math.max(offset, 0);
          
          // Mock空结果
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(0);

          const response = await controller.getUserList(safeLimit, safeOffset);

          expect(response.success).toBe(true);
          expect(response.data.items).toEqual([]);
          expect(response.data.total).toBe(0);
          expect(response.data.has_more).toBe(false);
          expect(response.data.limit).toBe(safeLimit);
          expect(response.data.offset).toBe(safeOffset);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 20 }
      );
    });
  });

  describe('Property 14: 分页限制保护', () => {
    it('超大limit值应该被限制到最大值', async () => {
      await PropertyTestRunner.runPropertyTest(
        '超大limit限制保护',
        () => ({
          limit: Math.floor(Math.random() * 9900) + 101, // 101-10000
          offset: Math.floor(Math.random() * 100)
        }),
        async ({ limit, offset }) => {
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(0);

          const response = await controller.getUserList(limit, offset);

          expect(response.success).toBe(true);
          expect(response.data.limit).toBeLessThanOrEqual(100); // 最大限制
          expect(response.data.limit).toBeGreaterThan(0);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 30 }
      );
    });

    it('负数limit值应该被修正为正数', async () => {
      await PropertyTestRunner.runPropertyTest(
        '负数limit修正保护',
        () => ({
          limit: -Math.floor(Math.random() * 100) - 1, // 负数
          offset: Math.floor(Math.random() * 100)
        }),
        async ({ limit, offset }) => {
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(0);

          const response = await controller.getUserList(limit, offset);

          expect(response.success).toBe(true);
          expect(response.data.limit).toBeGreaterThan(0); // 应该被修正为正数
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 20 }
      );
    });

    it('负数offset值应该被修正为0', async () => {
      await PropertyTestRunner.runPropertyTest(
        '负数offset修正保护',
        () => ({
          limit: Math.floor(Math.random() * 50) + 1,
          offset: -Math.floor(Math.random() * 100) - 1 // 负数
        }),
        async ({ limit, offset }) => {
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(0);

          const response = await controller.getUserList(limit, offset);

          expect(response.success).toBe(true);
          expect(response.data.offset).toBeGreaterThanOrEqual(0); // 应该被修正为非负数
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 20 }
      );
    });

    it('零值limit应该被修正为默认值', async () => {
      await PropertyTestRunner.runPropertyTest(
        '零值limit修正保护',
        () => ({
          limit: 0,
          offset: Math.floor(Math.random() * 100)
        }),
        async ({ limit, offset }) => {
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(0);

          const response = await controller.getUserList(limit, offset);

          expect(response.success).toBe(true);
          expect(response.data.limit).toBeGreaterThan(0); // 应该被修正为正数
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
      );
    });

    it('极大offset值应该返回空结果但不报错', async () => {
      await PropertyTestRunner.runPropertyTest(
        '极大offset处理保护',
        () => ({
          limit: Math.floor(Math.random() * 50) + 1,
          offset: Math.floor(Math.random() * 90000) + 10000 // 极大偏移
        }),
        async ({ limit, offset }) => {
          const totalItems = Math.floor(Math.random() * 1000) + 100;
          
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(totalItems);

          const response = await controller.getUserList(limit, offset);

          expect(response.success).toBe(true);
          
          // 当offset超过总数时，应该返回空结果
          if (offset >= totalItems) {
            expect(response.data.items).toEqual([]);
            expect(response.data.has_more).toBe(false);
          }
          
          expect(response.data.offset).toBe(offset); // offset应该保持原值
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 25 }
      );
    });

    it('分页保护机制应该在所有端点中一致', async () => {
      await PropertyTestRunner.runPropertyTest(
        '分页保护一致性',
        () => ({
          limit: Math.floor(Math.random() * 200) + 101, // 超过限制的值
          offset: -Math.floor(Math.random() * 50) - 1   // 负数偏移
        }),
        async ({ limit, offset }) => {
          // Mock所有服务
          mockUsersService.findAll.mockResolvedValueOnce([]);
          mockUsersService.count.mockResolvedValueOnce(0);
          
          mockUserProfilesService.findAll.mockResolvedValueOnce([]);
          mockUserProfilesService.count.mockResolvedValueOnce(0);
          
          mockZulipAccountsService.findMany.mockResolvedValueOnce({ accounts: [], total: 0 });

          // 测试所有列表端点
          const userResponse = await controller.getUserList(limit, offset);
          const profileResponse = await controller.getUserProfileList(limit, offset);
          const zulipResponse = await controller.getZulipAccountList(limit, offset);

          // 验证所有端点的保护机制一致
          [userResponse, profileResponse, zulipResponse].forEach(response => {
            expect(response.success).toBe(true);
            expect(response.data.limit).toBeLessThanOrEqual(100); // 最大限制
            expect(response.data.limit).toBeGreaterThan(0);       // 最小限制
            expect(response.data.offset).toBeGreaterThanOrEqual(0); // 非负偏移
          });
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 25 }
      );
    });
  });
});