/**
 * 时间展示工具
 * 规范：docs/miniprogram-dev/design-system/DATETIME-DISPLAY-STANDARD.md
 *
 * 规则（由近及远）：
 *   < 120s          → 刚刚
 *   2min ~ 59min    → N分钟前
 *   1h   ~ 23h      → N小时前
 *   1d   ~ 3d       → N天前
 *   > 3d 同年       → MM-DD
 *   > 3d 跨年       → YYYY-MM-DD
 */

/**
 * 将时间戳或 ISO 字符串格式化为相对时间文案
 * @param value Unix 毫秒时间戳 或 ISO 8601 字符串（如 "2026-03-10T16:30:00Z"）
 * @returns 格式化文案，如「刚刚」「2分钟前」「03-10」
 */
/**
 * 课时格式化
 * 整数 → Nh；非整数保留1位 → N.Nh；零值 → 0h；空值 → --
 */
export function formatHours(hours: number | null | undefined): string {
  if (hours === null || hours === undefined) return '--'
  if (hours === 0) return '0h'
  return hours % 1 === 0 ? `${hours}h` : `${hours.toFixed(1)}h`
}

/**
 * 任务截止日期语义化格式化
 * 规范：docs/miniprogram-dev/design-system/DISPLAY-STANDARDS-2.md §7
 *
 * @returns { text, style }
 *   style: 'muted'(灰) | 'normal'(正常) | 'warning'(橙/今天) | 'danger'(红/逾期)
 */
export function formatDeadline(
  deadline: string | null | undefined,
): { text: string; style: 'normal' | 'warning' | 'danger' | 'muted' } {
  if (!deadline) return { text: '--', style: 'muted' }
  const now = new Date()
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  const target = new Date(deadline)
  const targetDay = new Date(target.getFullYear(), target.getMonth(), target.getDate())
  const diff = Math.round((targetDay.getTime() - today.getTime()) / 86400000)
  if (diff < 0) return { text: `逾期 ${Math.abs(diff)} 天`, style: 'danger' }
  if (diff === 0) return { text: '今天到期', style: 'warning' }
  if (diff <= 7) return { text: `还剩 ${diff} 天`, style: 'normal' }
  const m = String(target.getMonth() + 1).padStart(2, '0')
  const d = String(target.getDate()).padStart(2, '0')
  return { text: `${m}-${d}`, style: 'muted' }
}

export function formatRelativeTime(value: number | string | undefined | null): string {
  if (value === undefined || value === null || value === '') return '--'

  const normalized = typeof value === 'string'
    ? value.replace(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})/, '$1T$2')
    : value
  const ts = typeof normalized === 'number' ? normalized : new Date(normalized).getTime()
  if (isNaN(ts)) return '--'

  const now = Date.now()
  const diff = Math.floor((now - ts) / 1000) // 秒

  // 未来时间（服务端时钟偏差）按「刚刚」处理
  if (diff < 120) return '刚刚'
  if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`
  if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`
  if (diff < 259200) return `${Math.floor(diff / 86400)}天前`

  const date = new Date(ts)
  const nowDate = new Date(now)
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')

  if (year === nowDate.getFullYear()) return `${month}-${day}`
  return `${year}-${month}-${day}`
}

/**
 * IM 气泡内时间戳格式
 * 今天内      → HH:mm
 * 今年非今天  → MM-DD HH:mm
 * 跨年        → YYYY-MM-DD HH:mm
 */
export function formatIMTime(value: number | string | undefined | null): string {
  if (value === undefined || value === null || value === '') return ''
  const normalized = typeof value === 'string'
    ? value.replace(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})/, '$1T$2')
    : value
  const ts = typeof normalized === 'number' ? normalized : new Date(normalized).getTime()
  if (isNaN(ts)) return ''

  const date = new Date(ts)
  const now = new Date()
  const hh = String(date.getHours()).padStart(2, '0')
  const mn = String(date.getMinutes()).padStart(2, '0')
  const timeStr = `${hh}:${mn}`
  const isSameDay =
    date.getFullYear() === now.getFullYear() &&
    date.getMonth() === now.getMonth() &&
    date.getDate() === now.getDate()
  if (isSameDay) return timeStr

  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  if (date.getFullYear() === now.getFullYear()) return `${month}-${day} ${timeStr}`
  return `${date.getFullYear()}-${month}-${day} ${timeStr}`
}

/**
 * 短日期格式化
 * "3月15日" / "--"
 */
export function formatDateShort(date: string | Date | null | undefined): string {
  if (!date) return '--'
  const d = typeof date === 'string' ? new Date(date) : date
  if (isNaN(d.getTime())) return '--'
  return `${d.getMonth() + 1}月${d.getDate()}日`
}

/**
 * 完整日期格式化
 * "2026-03-15" / "--"
 */
export function formatDateFull(date: string | Date | null | undefined): string {
  if (!date) return '--'
  const d = typeof date === 'string' ? new Date(date) : date
  if (isNaN(d.getTime())) return '--'
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${day}`
}

/**
 * 天数格式化
 * "3天" / "--"
 */
export function formatDays(days: number | null | undefined): string {
  if (days === null || days === undefined || days === 0) return '--'
  return `${days}天`
}

/**
 * 判断相邻消息是否需要显示时间分割线（间隔 >= 5 分钟，首条始终显示）
 */
export function shouldShowTimeDivider(
  prevTimestamp: number | string | null | undefined,
  currTimestamp: number | string | undefined | null,
): boolean {
  if (!prevTimestamp) return true
  const normPrev = typeof prevTimestamp === 'string' ? prevTimestamp.replace(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})/, '$1T$2') : prevTimestamp
  const normCurr = typeof currTimestamp === 'string' ? (currTimestamp as string).replace(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})/, '$1T$2') : currTimestamp
  const prev = typeof normPrev === 'number' ? normPrev : new Date(normPrev).getTime()
  const curr = typeof normCurr === 'number' ? normCurr : new Date(normCurr as string).getTime()
  if (isNaN(prev) || isNaN(curr)) return false
  return curr - prev >= 5 * 60 * 1000
}
