/**
 * Fiscal week, as the classic ASP site computed it.
 *
 * That site called it "Fiscal Week" and calculated an ISO 8601 week number
 * (includes/leftsidebar.asp): week 1 is the week containing 4 January, weeks
 * start on Monday, and the year is decided by that week's Thursday. This is a
 * faithful port - the label and the arithmetic both come from there.
 *
 * Worth knowing if the numbers are ever questioned: a true GE fiscal calendar
 * need not line up with ISO weeks. Nobody has asked for a different rule, and
 * changing it here would silently disagree with the classic site people still
 * compare against, so it stays ISO until someone says otherwise.
 */

/**
 * ISO 8601 week number for a date (1-53).
 *
 * Works in local time deliberately: the number people quote is the one on the
 * wall where they are, and a UTC-based week rolls over hours early in the
 * evening at a US site.
 */
export function fiscalWeek(date = new Date()) {
  const day = new Date(date.getFullYear(), date.getMonth(), date.getDate())

  // The Thursday of this week decides which year the week belongs to, which is
  // what makes late December and early January land in the right year.
  const dayOfWeek = (day.getDay() + 6) % 7        // 0 = Monday
  const thursday = new Date(day)
  thursday.setDate(day.getDate() + 3 - dayOfWeek)

  // Week 1 is the week containing 4 January; find its Monday.
  const jan4 = new Date(thursday.getFullYear(), 0, 4)
  const jan4DayOfWeek = (jan4.getDay() + 6) % 7
  const week1Monday = new Date(jan4)
  week1Monday.setDate(jan4.getDate() - jan4DayOfWeek)

  const days = Math.round((thursday - week1Monday) / 86400000)
  return Math.floor(days / 7) + 1
}

/** The year the week belongs to, which is not always the calendar year. */
export function fiscalWeekYear(date = new Date()) {
  const day = new Date(date.getFullYear(), date.getMonth(), date.getDate())
  const dayOfWeek = (day.getDay() + 6) % 7
  const thursday = new Date(day)
  thursday.setDate(day.getDate() + 3 - dayOfWeek)
  return thursday.getFullYear()
}
