import "server-only"

import { getClassNameById } from "@/modules/classes/data-access"
import { getSubjectOptions } from "@/modules/school/data-access"
import { getUserNamesByIds } from "@/modules/users/data-access"
import type { DataScope } from "@/shared/types/permissions"
import { exportToExcel } from "@/shared/lib/excel"

import { getClassGradeStats, getGradeRecords } from "./data-access"
import type { GradeRecordType } from "./types"

const TYPE_LABELS: Record<GradeRecordType, string> = {
  exam: "考试",
  quiz: "测验",
  homework: "作业",
  other: "其他",
}

/**
 * 导出成绩单
 * Sheet 1: 成绩明细
 * Sheet 2: 统计汇总
 */
export async function exportGradeRecordsToExcel(params: {
  classId: string
  subjectId?: string
  examId?: string
  scope: DataScope
}): Promise<Buffer> {
  const records = await getGradeRecords({
    scope: params.scope,
    classId: params.classId,
    subjectId: params.subjectId,
    examId: params.examId,
  })

  const detailRows = records.map((r) => ({
    studentName: r.studentName,
    className: r.className,
    subjectName: r.subjectName,
    title: r.title,
    score: r.score,
    fullScore: r.fullScore,
    type: TYPE_LABELS[r.type] ?? r.type,
    semester: r.semester === "1" ? "第一学期" : "第二学期",
    recorderName: r.recorderName,
    remark: r.remark ?? "",
    createdAt: r.createdAt.split("T")[0],
  }))

  const stats = await getClassGradeStats(params.classId, params.subjectId, params.examId)
  const statsRows = stats
    ? [
        { metric: "均分", value: stats.average },
        { metric: "中位数", value: stats.median },
        { metric: "最高分", value: stats.max },
        { metric: "最低分", value: stats.min },
        { metric: "标准差", value: stats.stdDev },
        { metric: "及格率(%)", value: stats.passRate },
        { metric: "优秀率(%)", value: stats.excellentRate },
        { metric: "参考人数", value: stats.count },
      ]
    : [{ metric: "无数据", value: "" }]

  return exportToExcel({
    sheets: [
      {
        name: "成绩明细",
        columns: [
          { header: "学生姓名", key: "studentName", width: 16 },
          { header: "班级", key: "className", width: 20 },
          { header: "科目", key: "subjectName", width: 14 },
          { header: "标题", key: "title", width: 24 },
          { header: "分数", key: "score", width: 10 },
          { header: "满分", key: "fullScore", width: 10 },
          { header: "类型", key: "type", width: 10 },
          { header: "学期", key: "semester", width: 12 },
          { header: "录入人", key: "recorderName", width: 14 },
          { header: "备注", key: "remark", width: 24 },
          { header: "录入日期", key: "createdAt", width: 14 },
        ],
        rows: detailRows,
      },
      {
        name: "统计汇总",
        columns: [
          { header: "指标", key: "metric", width: 20 },
          { header: "数值", key: "value", width: 16 },
        ],
        rows: statsRows,
      },
    ],
  })
}

/**
 * 导出班级成绩总表（多科目横向对比）
 */
export async function exportClassGradeReportToExcel(params: {
  classId: string
  scope: DataScope
}): Promise<Buffer> {
  const className = (await getClassNameById(params.classId)) ?? "Unknown"

  // Get all grade records for this class (already includes student/subject names via cross-module interfaces)
  const allRecords = await getGradeRecords({
    scope: params.scope,
    classId: params.classId,
  })

  // Extract unique subjects and students from the records
  const subjectIds = Array.from(new Set(allRecords.map((r) => r.subjectId).filter((v): v is string => typeof v === "string" && v.length > 0)))
  const studentIds = Array.from(new Set(allRecords.map((r) => r.studentId)))

  const [subjectOptions, studentNameMap] = await Promise.all([
    getSubjectOptions(),
    getUserNamesByIds(studentIds),
  ])

  const subjectNameById = new Map<string, string>()
  for (const s of subjectOptions) subjectNameById.set(s.id, s.name)

  const subjectRows = subjectIds
    .map((id) => {
      const name = subjectNameById.get(id)
      return name ? { id, name } : null
    })
    .filter((s): s is { id: string; name: string } => s !== null)

  const studentRows = studentIds
    .map((id) => {
      const info = studentNameMap.get(id)
      return { id, name: info?.name ?? "Unknown" }
    })
    .sort((a, b) => a.name.localeCompare(b.name))

  // Build a map: studentId -> subjectId -> average score
  const scoreMap = new Map<string, Map<string, number[]>>()
  for (const r of allRecords) {
    if (!scoreMap.has(r.studentId)) scoreMap.set(r.studentId, new Map())
    const subjMap = scoreMap.get(r.studentId)
    if (!subjMap) continue
    const arr = subjMap.get(r.subjectId) ?? []
    arr.push(r.score)
    subjMap.set(r.subjectId, arr)
  }

  const avg = (arr: number[]) =>
    arr.length > 0 ? Math.round((arr.reduce((a, b) => a + b, 0) / arr.length) * 100) / 100 : 0

  const columns = [
    { header: "学生姓名", key: "studentName", width: 16 },
    ...subjectRows.map((s) => ({
      header: s.name,
      key: s.id,
      width: 14,
    })),
    { header: "总分", key: "_total", width: 12 },
    { header: "平均分", key: "_average", width: 12 },
    { header: "排名", key: "_rank", width: 10 },
  ]

  const rowsData = studentRows.map((student) => {
    const subjMap = scoreMap.get(student.id) ?? new Map<string, number[]>()
    const row: Record<string, unknown> = {
      studentName: student.name,
    }
    let total = 0
    let count = 0
    for (const subj of subjectRows) {
      const scores = subjMap.get(subj.id) ?? []
      const score = avg(scores)
      row[subj.id] = scores.length > 0 ? score : "-"
      if (scores.length > 0) {
        total += score
        count++
      }
    }
    row["_total"] = total
    row["_average"] = count > 0 ? Math.round((total / count) * 100) / 100 : 0
    return { row, total }
  })

  // Rank by total descending
  rowsData.sort((a, b) => b.total - a.total)
  const rows = rowsData.map((d, idx) => ({
    ...d.row,
    _rank: idx + 1,
  }))

  return exportToExcel({
    sheets: [
      {
        name: `${className}_成绩总表`,
        columns,
        rows,
      },
    ],
  })
}
