import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { StudentProfile } from '../entities/student-profile.entity';
import { StudentEnrollment } from '../entities/student-enrollment.entity';
import { ExamScore } from '../entities/exam-score.entity';
import { LearningRecord } from '../entities/learning-record.entity';
import { ResultArchive } from '../entities/result-archive.entity';
import { AttendanceRecord } from '../entities/attendance-record.entity';
import { Student } from '../entities/student.entity';
import { ARCHIVE_REPORT_CSS } from './archive-report.styles';
import { esc } from './archive-report.helpers';
import { buildCover, buildBasicInfo } from './archive-report.cover';
import { buildExamOverview, buildExamDetail } from './archive-report.exam';
import { buildAttendance } from './archive-report.attendance';
import { buildLearning, buildResult } from './archive-report.learning';

interface ReportData {
  student: Student;
  profile: StudentProfile | null;
  enrollments: StudentEnrollment[];
  exams: ExamScore[];
  learnings: LearningRecord[];
  result: ResultArchive | null;
  attendances: AttendanceRecord[];
}

@Injectable()
export class ArchiveReportService {
  constructor(
    @InjectRepository(StudentProfile) private profileRepo: Repository<StudentProfile>,
    @InjectRepository(StudentEnrollment) private enrollmentRepo: Repository<StudentEnrollment>,
    @InjectRepository(ExamScore) private examRepo: Repository<ExamScore>,
    @InjectRepository(LearningRecord) private learningRepo: Repository<LearningRecord>,
    @InjectRepository(ResultArchive) private resultRepo: Repository<ResultArchive>,
    @InjectRepository(AttendanceRecord) private attendanceRepo: Repository<AttendanceRecord>,
    @InjectRepository(Student) private studentRepo: Repository<Student>,
  ) {}

  async generateReportHtml(studentId: number): Promise<string> {
    const [student, profile, enrollments, exams, learnings, result, attendances] =
      await Promise.all([
        this.studentRepo.findOne({ where: { id: studentId } }),
        this.profileRepo.findOne({ where: { studentId } }),
        this.enrollmentRepo.find({ where: { studentId }, order: { startDate: 'ASC' } }),
        this.examRepo.find({ where: { studentId }, order: { examDate: 'ASC' } }),
        this.learningRepo.find({ where: { studentId }, order: { recordDate: 'DESC' } }),
        this.resultRepo.findOne({ where: { studentId } }),
        this.attendanceRepo.find({ where: { studentId }, order: { attendanceDate: 'ASC' } }),
      ]);

    if (!student) throw new Error('学生不存在');

    return this.buildHtml({
      student,
      profile,
      enrollments,
      exams,
      learnings,
      result,
      attendances,
    });
  }

  private buildHtml(data: ReportData): string {
    const { student, profile, enrollments, exams, learnings, result, attendances } = data;
    const name = student.name;
    const now = new Date().toLocaleDateString('zh-CN', {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
    });

    const sections = [
      {
        name: enrollments.length > 0 ? '基础信息与报读记录' : '基础信息',
        html: buildBasicInfo(student, profile, enrollments, now),
      },
      { name: '考试成绩总览', html: buildExamOverview(exams, now) },
      { name: '出勤记录', html: buildAttendance(attendances, now) },
      { name: '文化课考试成绩', html: buildExamDetail(exams, now) },
      { name: '学情记录', html: buildLearning(learnings, now) },
      { name: '录取归档', html: buildResult(result, now) },
    ].filter((section) => section.html.length > 0);

    const cover = buildCover(
      student,
      profile,
      enrollments,
      now,
      sections.map((section) => section.name),
    );

    return `<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>学生档案报告 - ${esc(name)}</title>
<style>${ARCHIVE_REPORT_CSS}</style></head>
<body>
${cover}
${sections.map((section) => section.html).join('\n')}
</body></html>`;
  }
}
