/**
 * 仪表盘纯逻辑工具函数（与 UI 分离，便于单测）。
 *
 * 所有函数均为纯函数：相同输入 → 相同输出，无副作用。
 */

import type {
  HomeworkAssignmentListItem,
  HomeworkSubmissionListItem,
  StudentHomeworkAssignmentListItem,
  StudentHomeworkProgressStatus,
  TeacherGradeTrendItem,
} from "@/modules/homework/types"
import type { ClassScheduleItem, TeacherClass } from "@/modules/classes/types"

import type {
  StudentTodayScheduleItem,
  TeacherTodayScheduleItem,
  TeacherDashboardData,
} from "@/modules/dashboard/types"

/** 周一=1 ... 周日=7 */
export type Weekday = 1 | 2 | 3 | 4 | 5 | 6 | 7

/**
 * 将 Date 转换为 1-7 周几表示（周一=1，周日=7）。
 * getDay() 返回 0(周日)-6(周六)，需映射为 1-7。
 */
export function toWeekday(d: Date): Weekday {
  const day = d.getDay()
  if (day < 0 || day > 6) {
    throw new Error(`Invalid day from getDay(): ${day}`)
  }
  const WEEKDAY_MAP: readonly Weekday[] = [7, 1, 2, 3, 4, 5, 6]
  return WEEKDAY_MAP[day]
}

/** 学生作业统计结果 */
export interface StudentAssignmentStats {
  dueSoonCount: number
  overdueCount: number
  gradedCount: number
}

/**
 * 单次遍历统计学生作业状态：即将到期 / 已逾期 / 已批改。
 */
export function countStudentAssignments(
  assignments: readonly StudentHomeworkAssignmentListItem[],
  now: Date,
  dueSoonWindowDays = 7,
): StudentAssignmentStats {
  const in7Days = new Date(now)
  in7Days.setDate(in7Days.getDate() + dueSoonWindowDays)

  let dueSoonCount = 0
  let overdueCount = 0
  let gradedCount = 0

  for (const a of assignments) {
    const status: StudentHomeworkProgressStatus = a.progressStatus
    if (status === "graded") {
      gradedCount++
      continue
    }
    if (!a.dueAt) continue
    const due = new Date(a.dueAt)
    if (due >= now && due <= in7Days) {
      dueSoonCount++
    } else if (due < now) {
      overdueCount++
    }
  }

  return { dueSoonCount, overdueCount, gradedCount }
}

/**
 * 按截止日期升序排序作业，取前 N 条作为「即将到期」列表。
 * 无截止日期的作业排到最后。
 */
export function sortUpcomingAssignments(
  assignments: readonly StudentHomeworkAssignmentListItem[],
  limit = 6,
): StudentHomeworkAssignmentListItem[] {
  return [...assignments]
    .sort((a, b) => {
      const aDue = a.dueAt ? new Date(a.dueAt).getTime() : Number.POSITIVE_INFINITY
      const bDue = b.dueAt ? new Date(b.dueAt).getTime() : Number.POSITIVE_INFINITY
      return aDue - bDue
    })
    .slice(0, limit)
}

/**
 * 从课表中筛选指定周几的课程，按开始时间升序排序。
 */
export function filterTodaySchedule(
  schedule: readonly ClassScheduleItem[],
  weekday: Weekday,
  classNameById?: ReadonlyMap<string, string>,
): StudentTodayScheduleItem[] | TeacherTodayScheduleItem[] {
  return schedule
    .filter((s) => s.weekday === weekday)
    .sort((a, b) => a.startTime.localeCompare(b.startTime))
    .map((s) => ({
      id: s.id,
      classId: s.classId,
      className: classNameById?.get(s.classId) ?? "Class",
      course: s.course,
      startTime: s.startTime,
      endTime: s.endTime,
      location: s.location ?? null,
    })) as StudentTodayScheduleItem[] | TeacherTodayScheduleItem[]
}

/** 教师仪表盘派生指标 */
export interface TeacherDashboardMetrics {
  todayScheduleItems: TeacherTodayScheduleItem[]
  toGradeCount: number
  submissionsToGrade: HomeworkSubmissionListItem[]
  activeAssignmentsCount: number
  averageScore: number
  submissionRate: number
}

/**
 * 计算教师仪表盘派生指标：待批改数、进行中作业数、平均分、提交率等。
 */
export function computeTeacherMetrics(
  classes: readonly TeacherClass[],
  schedule: readonly ClassScheduleItem[],
  assignments: readonly HomeworkAssignmentListItem[],
  submissions: readonly HomeworkSubmissionListItem[],
  gradeTrends: readonly TeacherGradeTrendItem[],
  now: Date,
): TeacherDashboardMetrics {
  const todayWeekday = toWeekday(now)
  const classNameById = new Map(classes.map((c) => [c.id, c.name] as const))

  const todayScheduleItems = filterTodaySchedule(
    schedule,
    todayWeekday,
    classNameById,
  ) as TeacherTodayScheduleItem[]

  const submittedSubmissions = submissions.filter((s) => Boolean(s.submittedAt))
  const toGradeCount = submittedSubmissions.filter((s) => s.status === "submitted").length

  const submissionsToGrade = submittedSubmissions
    .filter((s) => s.status === "submitted")
    .sort(
      (a, b) =>
        (a.submittedAt ? new Date(a.submittedAt).getTime() : 0) -
        (b.submittedAt ? new Date(b.submittedAt).getTime() : 0),
    )
    .slice(0, 6)

  const activeAssignmentsCount = assignments.filter((a) => a.status === "published").length

  const totalTrendScore = gradeTrends.reduce((acc, curr) => acc + curr.averageScore, 0)
  const averageScore = gradeTrends.length > 0 ? totalTrendScore / gradeTrends.length : 0

  const totalSubmissions = gradeTrends.reduce((acc, curr) => acc + curr.submissionCount, 0)
  const totalPotentialSubmissions = gradeTrends.reduce((acc, curr) => acc + curr.totalStudents, 0)
  const submissionRate =
    totalPotentialSubmissions > 0 ? (totalSubmissions / totalPotentialSubmissions) * 100 : 0

  return {
    todayScheduleItems,
    toGradeCount,
    submissionsToGrade,
    activeAssignmentsCount,
    averageScore,
    submissionRate,
  }
}

/**
 * 根据当前小时返回问候语时段 key（morning / afternoon / evening）。
 */
export function getGreetingKey(now: Date): "morning" | "afternoon" | "evening" {
  const hour = now.getHours()
  if (hour < 12) return "morning"
  if (hour < 18) return "afternoon"
  return "evening"
}

/** 重导出 TeacherDashboardData 便于 actions 使用 */
export type { TeacherDashboardData }
