import { BadRequestException } from '@nestjs/common';
import { ClassroomRentalsService } from './classroom-rentals.service';
import { RentalScheduleService } from './rental-schedule.service';

describe('ClassroomRentalsService.purge', () => {
  const createService = (overrides?: {
    rental?: Record<string, unknown>;
    schedules?: Record<string, unknown>[];
    sessionCount?: number;
    recordCount?: number;
  }) => {
    const rental = {
      id: 1,
      classroomId: 2,
      status: 'cancelled',
      startDate: '2026-01-01',
      endDate: '2026-01-31',
      contractPath: null,
      ...overrides?.rental,
    };
    const repo = {
      findOne: jest.fn().mockResolvedValue(rental),
      delete: jest.fn().mockResolvedValue({ affected: 1 }),
    };
    const scheduleRepo = {
      find: jest.fn().mockResolvedValue(overrides?.schedules ?? []),
    };
    const attendanceRepo = { count: jest.fn().mockResolvedValue(overrides?.recordCount ?? 0) };
    const attendanceSessionRepo = {
      count: jest.fn().mockResolvedValue(overrides?.sessionCount ?? 0),
    };
    const manager = {
      delete: jest.fn().mockResolvedValue({ affected: 1 }),
    };
    const dataSource = {
      transaction: jest.fn(async (cb: (m: unknown) => Promise<unknown>) => cb(manager)),
    };
    const scheduleService = new RentalScheduleService(repo as never, {} as never, scheduleRepo as never);
    const service = new ClassroomRentalsService(
      repo as never,
      {} as never,
      {} as never,
      scheduleRepo as never,
      attendanceRepo as never,
      attendanceSessionRepo as never,
      dataSource as never,
      scheduleService,
    );
    return { service, repo, scheduleRepo, attendanceRepo, attendanceSessionRepo, dataSource, manager };
  };

  it('rejects rentals that are not cancelled', async () => {
    const { service, dataSource } = createService({ rental: { status: 'active' } });
    await expect(service.purge(1)).rejects.toThrow(
      new BadRequestException('仅已取消租赁订单可以永久删除，请先取消'),
    );
    expect(dataSource.transaction).not.toHaveBeenCalled();
  });

  it('rejects cancelled rentals whose schedules have attendance history', async () => {
    const withSession = createService({
      schedules: [{ id: 5, rentalId: 1, scheduleType: 'RENTAL' }],
      sessionCount: 1,
    });
    await expect(withSession.service.purge(1)).rejects.toThrow(
      new BadRequestException('该租赁的排课已有考勤记录，无法永久删除'),
    );

    const withRecord = createService({
      schedules: [{ id: 5, rentalId: 1, scheduleType: 'RENTAL' }],
      recordCount: 1,
    });
    await expect(withRecord.service.purge(1)).rejects.toThrow(
      new BadRequestException('该租赁的排课已有考勤记录，无法永久删除'),
    );
    expect(withRecord.dataSource.transaction).not.toHaveBeenCalled();
  });

  it('deletes schedules and rental without attendance history', async () => {
    const { service, dataSource, manager } = createService({
      schedules: [{ id: 5, rentalId: 1, scheduleType: 'RENTAL' }],
    });
    await expect(service.purge(1)).resolves.toEqual({
      message: '已永久删除租赁订单（不可恢复）',
    });
    expect(dataSource.transaction).toHaveBeenCalled();
    expect(manager.delete).toHaveBeenNthCalledWith(1, expect.anything(), {
      id: expect.anything(),
    });
    expect(manager.delete).toHaveBeenNthCalledWith(2, expect.anything(), 1);
  });
});
