import { BadRequestException } from '@nestjs/common';
import { ExpensesService } from './expenses.service';
import { ExpenseOperationsService } from './expense-operations.service';

describe('ExpensesService purge', () => {
  const billItemsRepo = {
    count: jest.fn().mockResolvedValue(0),
  };
  const dataSource = {
    getRepository: jest.fn().mockReturnValue(billItemsRepo),
  };
  const roomExpRepo = {
    findOne: jest.fn(),
    delete: jest.fn().mockResolvedValue({ affected: 1 }),
    find: jest.fn(),
  };
  const personalExpRepo = {
    findOne: jest.fn(),
    delete: jest.fn().mockResolvedValue({ affected: 1 }),
    find: jest.fn(),
  };

  const createService = () =>
    new ExpensesService(
      roomExpRepo as never,
      personalExpRepo as never,
      {} as never,
      {} as never,
      {} as never,
      dataSource as never,
      new ExpenseOperationsService(
        roomExpRepo as never,
        personalExpRepo as never,
        {} as never,
        {} as never,
        {} as never,
        dataSource as never,
      ),
    );

  beforeEach(() => {
    jest.clearAllMocks();
    billItemsRepo.count.mockResolvedValue(0);
  });

  it('room expense purge rejects non-archived records', async () => {
    roomExpRepo.findOne.mockResolvedValue({ id: 1, status: 'active' });
    const service = createService();
    await expect(service.purgeRoomExpense(1)).rejects.toThrow(
      new BadRequestException('仅已归档费用可以永久删除，请先归档'),
    );
    expect(roomExpRepo.delete).not.toHaveBeenCalled();
  });

  it('room expense purge rejects billed records', async () => {
    roomExpRepo.findOne.mockResolvedValue({ id: 1, status: 'archived' });
    billItemsRepo.count.mockResolvedValue(1);
    const service = createService();
    await expect(service.purgeRoomExpense(1)).rejects.toThrow(
      new BadRequestException('已计入账单的宿舍费用不能永久删除，请先取消账单'),
    );
    expect(roomExpRepo.delete).not.toHaveBeenCalled();
  });

  it('room expense purge deletes archived records', async () => {
    roomExpRepo.findOne.mockResolvedValue({ id: 1, status: 'archived' });
    const service = createService();
    await expect(service.purgeRoomExpense(1)).resolves.toEqual({
      message: '已永久删除宿舍费用（不可恢复）',
    });
    expect(roomExpRepo.delete).toHaveBeenCalledWith(1);
  });

  it('personal expense purge rejects records attached to a bill', async () => {
    personalExpRepo.findOne.mockResolvedValue({ id: 1, status: 'archived', billId: 9 });
    const service = createService();
    await expect(service.purgePersonalExpense(1)).rejects.toThrow(
      new BadRequestException('已计入账单的个人费用不能永久删除，请先取消账单'),
    );
    expect(personalExpRepo.delete).not.toHaveBeenCalled();
  });

  it('personal expense purge deletes archived records with no bill', async () => {
    personalExpRepo.findOne.mockResolvedValue({ id: 1, status: 'archived', billId: null });
    const service = createService();
    await expect(service.purgePersonalExpense(1)).resolves.toEqual({
      message: '已永久删除个人费用（不可恢复）',
    });
    expect(personalExpRepo.delete).toHaveBeenCalledWith(1);
  });
});
