import type { AttendanceTrendPoint } from "./types"

/**
 * L-4：趋势粒度类型。
 */
export type TrendGranularity = "daily" | "weekly" | "monthly"

/**
 * 将日期字符串（YYYY-MM-DD）按粒度分组的 bucket key。
 * - daily：返回原日期
 * - weekly：返回该日期所在周的周一日期（ISO 周一为一周开始）
 * - monthly：返回该日期所在月份的第一天（YYYY-MM-01）
 */
export const bucketizeDate = (dateStr: string, granularity: TrendGranularity): string => {
  if (granularity === "daily") return dateStr

  const d = new Date(dateStr)
  if (Number.isNaN(d.getTime())) return dateStr

  if (granularity === "weekly") {
    // ISO 周一为一周开始：getDay() 周日=0, 周一=1, ... 周六=6
    const day = d.getDay()
    const diff = day === 0 ? -6 : 1 - day // 周日回到上周一，其他回到本周一
    const monday = new Date(d)
    monday.setDate(d.getDate() + diff)
    return monday.toISOString().slice(0, 10)
  }

  // monthly
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-01`
}

/**
 * 格式化 bucket key 为显示标签。
 * - daily：MM-DD
 * - weekly：MM-DD（周一日期）
 * - monthly：YYYY-MM
 */
export const formatBucketLabel = (bucketKey: string, granularity: TrendGranularity): string => {
  if (granularity === "monthly") {
    return bucketKey.slice(0, 7) // YYYY-MM
  }
  return bucketKey.slice(5) // MM-DD
}

/**
 * L-4：从按日期的原始记录列表计算趋势数据点（纯函数，便于测试）。
 *
 * @param records 记录列表，每项含 date（YYYY-MM-DD）和 status
 * @param granularity 聚合粒度
 * @returns 按 bucket key 升序的趋势数据点
 */
export const computeTrendPoints = (
  records: { date: string; status: string }[],
  granularity: TrendGranularity
): AttendanceTrendPoint[] => {
  if (records.length === 0) return []

  // 按 bucket 聚合
  const buckets = new Map<string, { total: number; present: number; late: number; absent: number }>()

  for (const r of records) {
    const bucket = bucketizeDate(r.date, granularity)
    const stat = buckets.get(bucket) ?? { total: 0, present: 0, late: 0, absent: 0 }
    stat.total += 1
    if (r.status === "present") stat.present += 1
    else if (r.status === "late") stat.late += 1
    else if (r.status === "absent") stat.absent += 1
    buckets.set(bucket, stat)
  }

  // 按 bucket key 升序转换为趋势点
  const sortedBuckets = Array.from(buckets.entries()).sort(([a], [b]) => a.localeCompare(b))

  return sortedBuckets.map(([bucket, stat]) => {
    const { total, present, late, absent } = stat
    return {
      date: bucket,
      presentRate: total > 0 ? Math.round((present / total) * 10000) / 100 : 0,
      lateRate: total > 0 ? Math.round((late / total) * 10000) / 100 : 0,
      absentRate: total > 0 ? Math.round((absent / total) * 10000) / 100 : 0,
      total,
    }
  })
}
