import { BadRequestException } from '@nestjs/common';
import { ExamsService } from './exams.service';

describe('ExamsService.purge', () => {
  const createService = (overrides?: { exam?: Record<string, unknown> }) => {
    const exam = { id: 1, examName: '月考', classId: 2, status: 'archived', ...overrides?.exam };
    const examRepo = {
      findOne: jest.fn().mockResolvedValue(exam),
      delete: jest.fn().mockResolvedValue({ affected: 1 }),
      find: jest.fn().mockResolvedValue([exam]),
    };
    const classTeacherRepo = { findOne: jest.fn().mockResolvedValue({}) };
    const service = new ExamsService(
      examRepo as never,
      {} as never,
      {} as never,
      {} as never,
      classTeacherRepo as never,
      {} as never,
    );
    return { service, examRepo, classTeacherRepo };
  };

  it('rejects exams that are not archived', async () => {
    const { service, examRepo } = createService({ exam: { status: 'active' } });
    await expect(service.purge(1, 7, true)).rejects.toThrow(
      new BadRequestException('仅已归档考试可以永久删除，请先归档'),
    );
    expect(examRepo.delete).not.toHaveBeenCalled();
  });

  it('deletes an archived exam and its scores', async () => {
    const { service, examRepo } = createService();
    await expect(service.purge(1, 7, true)).resolves.toEqual({
      message: '已永久删除考试（不可恢复）',
    });
    expect(examRepo.delete).toHaveBeenCalledWith(1);
  });

  it('checks class access before purge', async () => {
    const { service, classTeacherRepo } = createService();
    classTeacherRepo.findOne.mockResolvedValue(null);
    await expect(service.purge(1, 7, false)).rejects.toThrow('只能访问自己被分配的班级');
  });

  it('batch purge returns deleted and skipped', async () => {
    const { service, examRepo } = createService();
    examRepo.find = jest.fn().mockResolvedValue([
      { id: 1, examName: '月考', classId: 2, status: 'archived' },
      { id: 2, examName: '期中', classId: 2, status: 'active' },
    ]);
    const result = await service.batchPurge([1, 2], 7, true);
    expect(result).toMatchObject({ deleted: 1, skipped: 1 });
    expect(examRepo.delete).toHaveBeenCalledWith(1);
  });
});
