import { describe, it, expect, beforeEach, vi } from 'vitest';
import { DisabledPersonService } from '../../src/services/disabled-person.service';
import { DisabledPerson } from '../../src/entities/disabled-person.entity';
import { Repository, DataSource } from 'typeorm';
import { OrderPerson } from '@d8d/allin-order-module/entities';

describe('DisabledPersonService - findPersonsWithCompany', () => {
  let service: DisabledPersonService;
  let mockDataSource: Partial<DataSource>;
  let mockOrderPersonRepository: Partial<Repository<OrderPerson>>;
  let mockQueryBuilder: any;

  beforeEach(() => {
    // 创建 QueryBuilder 模拟
    mockQueryBuilder = {
      innerJoin: vi.fn().mockReturnThis(),
      leftJoin: vi.fn().mockReturnThis(),
      where: vi.fn().mockReturnThis(),
      andWhere: vi.fn().mockReturnThis(),
      select: vi.fn().mockReturnThis(),
      groupBy: vi.fn().mockReturnThis(),
      orderBy: vi.fn().mockReturnThis(),
      offset: vi.fn().mockReturnThis(),
      limit: vi.fn().mockReturnThis(),
      getRawMany: vi.fn().mockResolvedValue([]),
      getCount: vi.fn().mockResolvedValue(0),
      clone: vi.fn(function(this: any) { return this; })
    };

    // 创建 OrderPerson Repository 模拟
    mockOrderPersonRepository = {
      createQueryBuilder: vi.fn(() => mockQueryBuilder)
    };

    // 创建 DataSource 模拟
    mockDataSource = {
      getRepository: vi.fn((entity) => {
        if (entity === OrderPerson) {
          return mockOrderPersonRepository;
        }
        return {};
      })
    };

    // @ts-ignore - 创建实例
    service = new DisabledPersonService(mockDataSource as DataSource);
  });

  it('应该返回残疾人和公司的关联数据', async () => {
    // Arrange
    const mockResult = [
      {
        personid: 1,
        name: '张三',
        gender: '男',
        disabilitytype: '视力残疾',
        disabilitylevel: '一级',
        disabilityid: 'CJZ20240001',
        city: '北京市',
        district: '东城区',
        companyname: '测试企业',
        orderid: 100,
        joindate: '2024-01-01'
      }
    ];

    mockQueryBuilder.getRawMany.mockResolvedValue(mockResult);
    mockQueryBuilder.getCount.mockResolvedValue(1);

    // Act
    const result = await service.findPersonsWithCompany({
      gender: '男',
      page: 1,
      limit: 10
    });

    // Assert
    expect(result.data).toHaveLength(1);
    expect(result.data[0].name).toBe('张三');
    expect(result.data[0].companyName).toBe('测试企业');
    expect(result.total).toBe(1);
  });

  it('应该支持按性别筛选', async () => {
    // Arrange
    mockQueryBuilder.getRawMany.mockResolvedValue([]);
    mockQueryBuilder.getCount.mockResolvedValue(0);

    // Act
    await service.findPersonsWithCompany({
      gender: '女',
      page: 1,
      limit: 10
    });

    // Assert
    expect(mockQueryBuilder.andWhere).toHaveBeenCalledWith('person.gender = :gender', { gender: '女' });
  });

  it('应该支持按残疾类别筛选', async () => {
    // Arrange
    mockQueryBuilder.getRawMany.mockResolvedValue([]);
    mockQueryBuilder.getCount.mockResolvedValue(0);

    // Act
    await service.findPersonsWithCompany({
      disabilityType: '肢体残疾',
      page: 1,
      limit: 10
    });

    // Assert
    expect(mockQueryBuilder.andWhere).toHaveBeenCalledWith('person.disabilityType = :disabilityType', { disabilityType: '肢体残疾' });
  });

  it('应该支持按公司筛选', async () => {
    // Arrange
    mockQueryBuilder.getRawMany.mockResolvedValue([]);
    mockQueryBuilder.getCount.mockResolvedValue(0);

    // Act
    await service.findPersonsWithCompany({
      companyId: 1,
      page: 1,
      limit: 10
    });

    // Assert
    expect(mockQueryBuilder.andWhere).toHaveBeenCalledWith('order.companyId = :companyId', { companyId: 1 });
  });

  it('应该支持分页', async () => {
    // Arrange
    mockQueryBuilder.getRawMany.mockResolvedValue([]);
    mockQueryBuilder.getCount.mockResolvedValue(0);

    // Act
    await service.findPersonsWithCompany({
      page: 2,
      limit: 20
    });

    // Assert
    expect(mockQueryBuilder.offset).toHaveBeenCalledWith(20); // (2-1)*20
    expect(mockQueryBuilder.limit).toHaveBeenCalledWith(20);
  });
});
