import { ArchiveReportService } from './archive-report.service';

interface MockData {
  student?: Record<string, unknown>;
  profile?: Record<string, unknown> | null;
  enrollments?: Array<Record<string, unknown>>;
  exams?: Array<Record<string, unknown>>;
  learnings?: Array<Record<string, unknown>>;
  result?: Record<string, unknown> | null;
  attendances?: Array<Record<string, unknown>>;
}

function makeService(data: MockData = {}): ArchiveReportService {
  return new ArchiveReportService(
    { findOne: jest.fn().mockResolvedValue(data.profile ?? null) } as never,
    { find: jest.fn().mockResolvedValue(data.enrollments ?? []) } as never,
    { find: jest.fn().mockResolvedValue(data.exams ?? []) } as never,
    { find: jest.fn().mockResolvedValue(data.learnings ?? []) } as never,
    { findOne: jest.fn().mockResolvedValue(data.result ?? null) } as never,
    { find: jest.fn().mockResolvedValue(data.attendances ?? []) } as never,
    {
      findOne: jest.fn().mockResolvedValue(
        data.student ?? { id: 1, name: '测试学生', studentNo: 'S001' },
      ),
    } as never,
  );
}

describe('ArchiveReportService retired profile fields', () => {
  it('does not render the retired campus field in a student report', async () => {
    const service = makeService({
      profile: { campusLocation: '旧校区', grade: '高三' },
      student: {
        id: 1,
        name: '测试学生',
        gender: '男',
        phone: '',
        ethnicity: '',
        emergencyContact: '',
        emergencyPhone: '',
      },
    });

    const html = await service.generateReportHtml(1);

    expect(html).not.toContain('旧校区');
    expect(html).not.toContain('<span>校区</span>');
    expect(html).toContain('高三');
  });
});

describe('ArchiveReportService empty sections', () => {
  it('hides empty sections and removes fixed TOC page numbers', async () => {
    const service = makeService({ profile: { grade: '高三' } });
    const html = await service.generateReportHtml(1);

    expect(html).toContain('学生档案报告');
    expect(html).toContain('基础信息');
    expect(html).not.toContain('考试成绩总览');
    expect(html).not.toContain('出勤记录');
    expect(html).not.toContain('文化课考试成绩');
    expect(html).not.toContain('学情记录');
    expect(html).not.toContain('录取归档');
    expect(html).not.toContain('第 2 页');
    expect(html).not.toContain('暂无');
  });

  it('renders sections with data and lists only those sections in the TOC', async () => {
    const service = makeService({
      profile: { grade: '高三' },
      enrollments: [{ courseCategory: '文化课', classType: '全日制' }],
      exams: [
        {
          examType: '文化课月考',
          examName: '一月月考',
          subject: '数学',
          score: 88,
          examDate: '2026-01-10',
        },
      ],
      attendances: [
        { attendanceDate: '2026-01-12', session: '上午', status: 'present' },
      ],
      learnings: [
        {
          recordDate: '2026-01-13',
          recordType: '回访',
          content: '状态良好',
          followUpMethod: '电话',
        },
      ],
      result: {
        cultureFinalScore: 90,
        professionalFinalScore: 85,
        admissionStatus: '录取',
        admittedCollege: '示例大学',
        admittedMajor: '计算机',
      },
    });

    const html = await service.generateReportHtml(1);

    expect(html).toContain('考试成绩总览');
    expect(html).toContain('出勤记录');
    expect(html).toContain('文化课考试成绩');
    expect(html).toContain('学情记录');
    expect(html).toContain('录取归档');
    expect(html).toContain('<h3>报读记录</h3>');
    expect(html).not.toContain('第 1 页');
    expect(html).not.toContain('第 2 页');
  });

  it('omits the enrollment card when there are no enrollments', async () => {
    const service = makeService({ profile: { grade: '高三' } });
    const html = await service.generateReportHtml(1);

    expect(html).not.toContain('<h3>报读记录</h3>');
    expect(html).not.toContain('暂无报读记录');
  });
});
