import { BadRequestException } from '@nestjs/common';
import { OccupanciesService } from './occupancies.service';
import { OccupancyOperationsService } from './occupancy-operations.service';

describe('OccupanciesService.purge', () => {
  const createService = (overrides?: {
    occupancy?: Record<string, unknown>;
    detailCount?: number;
  }) => {
    const occ = { id: 1, status: 'archived', student: { name: '张三' }, ...overrides?.occupancy };
    const repo = {
      findOne: jest.fn().mockResolvedValue(occ),
      delete: jest.fn().mockResolvedValue({ affected: 1 }),
      find: jest.fn().mockResolvedValue([occ]),
    };
    const inspectionDetailRepo = {
      count: jest.fn().mockResolvedValue(overrides?.detailCount ?? 0),
    };
    const operations = new OccupancyOperationsService(
      repo as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      inspectionDetailRepo as never,
    );
    const service = new OccupanciesService(
      repo as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      inspectionDetailRepo as never,
      operations,
    );
    return { service, repo, inspectionDetailRepo };
  };

  it('rejects occupancies that are not archived', async () => {
    const { service, repo } = createService({ occupancy: { status: 'active' } });
    await expect(service.purge(1)).rejects.toThrow(
      new BadRequestException('仅已归档入住记录可以永久删除，请先归档'),
    );
    expect(repo.delete).not.toHaveBeenCalled();
  });

  it('rejects occupancies referenced by inspection details', async () => {
    const { service, repo } = createService({ detailCount: 1 });
    await expect(service.purge(1)).rejects.toThrow(
      new BadRequestException('该入住记录已被查寝记录引用，无法永久删除'),
    );
    expect(repo.delete).not.toHaveBeenCalled();
  });

  it('deletes an archived occupancy with no references', async () => {
    const { service, repo } = createService();
    await expect(service.purge(1)).resolves.toEqual({
      message: '已永久删除入住记录（不可恢复）',
    });
    expect(repo.delete).toHaveBeenCalledWith(1);
  });

  it('batch purge skips referenced records', async () => {
    const { service, repo, inspectionDetailRepo } = createService();
    repo.find = jest.fn().mockResolvedValue([
      { id: 1, status: 'archived', student: { name: '甲' } },
      { id: 2, status: 'archived', student: { name: '乙' } },
    ]);
    inspectionDetailRepo.count.mockResolvedValueOnce(1).mockResolvedValueOnce(0);
    const result = await service.batchPurge([1, 2]);
    expect(result).toMatchObject({ deleted: 1, skipped: 1 });
    expect(repo.delete).toHaveBeenCalledWith(2);
  });
});
