import "server-only"

import { getTranslations } from "next-intl/server"

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 { computeAverageScore } from "./stats-service"

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

  const records = await getGradeRecords({
    scope: params.scope,
    currentUserId: params.currentUserId,
    classId: params.classId,
    subjectId: params.subjectId,
    examId: params.examId,
  })

  const detailRows = records.records.map((r) => ({
    studentName: r.studentName,
    className: r.className,
    subjectName: r.subjectName,
    title: r.title,
    score: r.score,
    fullScore: r.fullScore,
    type: t(`type.${r.type}`),
    semester: t(`semester.${r.semester === "1" ? "s1" : "s2"}`),
    recorderName: r.recorderName,
    remark: r.remark ?? "",
    createdAt: r.createdAt.split("T")[0],
  }))

  // P3 修复：调用 getClassGradeStats 时传入 scope
  const stats = await getClassGradeStats(
    params.classId,
    params.subjectId,
    params.examId,
    params.scope,
    params.currentUserId
  )
  const statsRows = stats
    ? [
        { metric: t("export.metrics.average"), value: stats.average },
        { metric: t("export.metrics.median"), value: stats.median },
        { metric: t("export.metrics.max"), value: stats.max },
        { metric: t("export.metrics.min"), value: stats.min },
        { metric: t("export.metrics.stdDev"), value: stats.stdDev },
        { metric: t("export.metrics.passRate"), value: stats.passRate },
        { metric: t("export.metrics.excellentRate"), value: stats.excellentRate },
        { metric: t("export.metrics.count"), value: stats.count },
      ]
    : [{ metric: t("export.metrics.noData"), value: "" }]

  return exportToExcel({
    sheets: [
      {
        name: t("export.sheets.detail"),
        columns: [
          { header: t("export.columns.studentName"), key: "studentName", width: 16 },
          { header: t("export.columns.class"), key: "className", width: 20 },
          { header: t("export.columns.subject"), key: "subjectName", width: 14 },
          { header: t("export.columns.title"), key: "title", width: 24 },
          { header: t("export.columns.score"), key: "score", width: 10 },
          { header: t("export.columns.fullScore"), key: "fullScore", width: 10 },
          { header: t("export.columns.type"), key: "type", width: 10 },
          { header: t("export.columns.semester"), key: "semester", width: 12 },
          { header: t("export.columns.recorder"), key: "recorderName", width: 14 },
          { header: t("export.columns.remark"), key: "remark", width: 24 },
          { header: t("export.columns.date"), key: "createdAt", width: 14 },
        ],
        rows: detailRows,
      },
      {
        name: t("export.sheets.summary"),
        columns: [
          { header: t("export.columns.metric"), key: "metric", width: 20 },
          { header: t("export.columns.value"), key: "value", width: 16 },
        ],
        rows: statsRows,
      },
    ],
  })
}

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

  const className = (await getClassNameById(params.classId)) ?? "Unknown"

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

  // 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 columns = [
    { header: t("export.columns.studentName"), key: "studentName", width: 16 },
    ...subjectRows.map((s) => ({
      header: s.name,
      key: s.id,
      width: 14,
    })),
    { header: t("export.columns.total"), key: "_total", width: 12 },
    { header: t("export.columns.average"), key: "_average", width: 12 },
    { header: t("export.columns.rank"), 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 = computeAverageScore(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: t("export.sheets.classReport", { className }),
        columns,
        rows,
      },
    ],
  })
}

/**
 * v4-P1-12: 导出单个学生的成绩单（家长视角）。
 * 仅导出成绩明细，不含班级统计（家长无权查看全班数据）。
 */
export async function exportStudentGradeRecordsToExcel(params: {
  studentId: string
  subjectId?: string
  scope: DataScope
  currentUserId?: string
}): Promise<Buffer> {
  const t = await getTranslations("grades")

  // DB 层按 studentId 过滤，避免内存过滤性能问题
  const records = await getGradeRecords({
    scope: params.scope,
    currentUserId: params.currentUserId,
    studentId: params.studentId,
    subjectId: params.subjectId,
  })

  const studentRecords = records.records

  const detailRows = studentRecords.map((r) => ({
    studentName: r.studentName,
    className: r.className,
    subjectName: r.subjectName,
    title: r.title,
    score: r.score,
    fullScore: r.fullScore,
    type: t(`type.${r.type}`),
    semester: t(`semester.${r.semester === "1" ? "s1" : "s2"}`),
    recorderName: r.recorderName,
    remark: r.remark ?? "",
    createdAt: r.createdAt.split("T")[0],
  }))

  // 计算该学生的个人统计
  const scores = studentRecords.map((r) => r.score)
  const average = scores.length > 0
    ? Math.round((scores.reduce((a, b) => a + b, 0) / scores.length) * 100) / 100
    : 0
  const maxScore = scores.length > 0 ? Math.max(...scores) : 0
  const minScore = scores.length > 0 ? Math.min(...scores) : 0

  const statsRows = [
    { metric: t("export.metrics.count"), value: scores.length },
    { metric: t("export.metrics.average"), value: average },
    { metric: t("export.metrics.max"), value: maxScore },
    { metric: t("export.metrics.min"), value: minScore },
  ]

  return exportToExcel({
    sheets: [
      {
        name: t("export.sheets.detail"),
        columns: [
          { header: t("export.columns.studentName"), key: "studentName", width: 16 },
          { header: t("export.columns.class"), key: "className", width: 20 },
          { header: t("export.columns.subject"), key: "subjectName", width: 14 },
          { header: t("export.columns.title"), key: "title", width: 24 },
          { header: t("export.columns.score"), key: "score", width: 10 },
          { header: t("export.columns.fullScore"), key: "fullScore", width: 10 },
          { header: t("export.columns.type"), key: "type", width: 10 },
          { header: t("export.columns.semester"), key: "semester", width: 12 },
          { header: t("export.columns.recorder"), key: "recorderName", width: 14 },
          { header: t("export.columns.remark"), key: "remark", width: 24 },
          { header: t("export.columns.date"), key: "createdAt", width: 14 },
        ],
        rows: detailRows,
      },
      {
        name: t("export.sheets.summary"),
        columns: [
          { header: t("export.columns.metric"), key: "metric", width: 20 },
          { header: t("export.columns.value"), key: "value", width: 16 },
        ],
        rows: statsRows,
      },
    ],
  })
}
