import { BadRequestException, NotFoundException } from '@nestjs/common';
import { StudentsService } from './students.service';

function createService(repo: Record<string, jest.Mock>, organizationRepo = {}) {
  const profileRepo = { find: jest.fn().mockResolvedValue([]) };
  const resultRepo = { find: jest.fn().mockResolvedValue([]) };
  return new StudentsService(
    repo as never,
    {} as never,
    {} as never,
    {} as never,
    {} as never,
    organizationRepo as never,
    profileRepo as never,
    {} as never,
    {} as never,
    {} as never,
    resultRepo as never,
  );
}

describe('StudentsService — archive lifecycle boundaries', () => {
  it('rejects archiving an already archived student', async () => {
    const repo = { findOne: jest.fn().mockResolvedValue({ id: 1, status: 'archived' }) };
    await expect(createService(repo).remove(1)).rejects.toBeInstanceOf(BadRequestException);
  });

  it('rejects restoring a student that is not archived', async () => {
    const repo = { findOne: jest.fn().mockResolvedValue({ id: 1, status: 'active' }) };
    await expect(createService(repo).restore(1)).rejects.toBeInstanceOf(BadRequestException);
  });

  it('rejects an empty batch archive', async () => {
    await expect(createService({}).batchRemove([])).rejects.toBeInstanceOf(BadRequestException);
  });

  it('rejects creating a student under a missing or archived organization', async () => {
    const repo = { create: jest.fn(), save: jest.fn() };
    const organizationRepo = { findOne: jest.fn().mockResolvedValue(null) };
    await expect(
      createService(repo, organizationRepo).create({ name: '张三', organizationId: 9 }),
    ).rejects.toBeInstanceOf(BadRequestException);
    expect(repo.save).not.toHaveBeenCalled();
  });

  it('returns not found for a missing student', async () => {
    const repo = { findOne: jest.fn().mockResolvedValue(null) };
    await expect(createService(repo).findOne(404)).rejects.toBeInstanceOf(NotFoundException);
  });

  it('builds export archive maps from profile and result rows', async () => {
    const profileRepo = {
      find: jest.fn().mockResolvedValue([{
        studentId: 1,
        targetCollege: '北京大学',
        collegeSchool: '北京职业技术学院',
      }]),
    };
    const resultRepo = {
      find: jest.fn().mockResolvedValue([{ studentId: 1, admissionStatus: 'pending' }]),
    };
    const service = new StudentsService(
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      {} as never,
      profileRepo as never,
      {} as never,
      {} as never,
      {} as never,
      resultRepo as never,
    );

    const maps = await service.getArchiveExportMaps([1]);

    expect(maps.profiles.get(1)?.targetCollege).toBe('北京大学');
    expect(maps.profiles.get(1)?.collegeSchool).toBe('北京职业技术学院');
    expect(maps.results.get(1)?.admissionStatus).toBe('pending');
  });
});
