/** 将瞬时时刻换算为「上海」日历年月日（与后端 Asia/Shanghai 叙事一致）。 */
export function ymdInShanghai(ms: number): { y: number; m: number; d: number } {
  const s = new Intl.DateTimeFormat('en-CA', {
    timeZone: 'Asia/Shanghai',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).format(new Date(ms))
  const [y, m, d] = s.split('-').map((x) => Number.parseInt(x, 10))
  return { y, m, d }
}

/** 公历某月天数，month 为 1–12。 */
function daysInMonth(y: number, month: number): number {
  return new Date(y, month, 0).getDate()
}

/**
 * 从起点日历日到终点日历日的「年、月、日」差（与日常说的「在一起多久」同构）。
 * 假定 a 不晚于 b。
 */
export function calendarDiffYmd(
  a: { y: number; m: number; d: number },
  b: { y: number; m: number; d: number },
): { years: number; months: number; days: number } {
  let years = b.y - a.y
  let months = b.m - a.m
  let days = b.d - a.d
  if (days < 0) {
    months -= 1
    const prevMonth = b.m === 1 ? 12 : b.m - 1
    const prevYear = b.m === 1 ? b.y - 1 : b.y
    days += daysInMonth(prevYear, prevMonth)
  }
  if (months < 0) {
    years -= 1
    months += 12
  }
  return { years, months, days }
}

/** 从起点到当前的累计小时数（可带小数，用于「相当于多少小时」）。 */
export function totalHoursBetween(startMs: number, endMs: number, fractionDigits = 1): number {
  const ms = Math.max(0, endMs - startMs)
  const h = ms / 3_600_000
  const p = 10 ** fractionDigits
  return Math.round(h * p) / p
}
