import { WEEKDAYS } from "./useHoursApi.js";

export { WEEKDAYS };

/** @param {Date} d */
export function toYmd(d) {
  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}`;
}

export function todayIsoLocal() {
  return toYmd(new Date());
}

/** Monday (local) for the calendar week containing `dayIso` (YYYY-MM-DD). */
export function mondayIsoForLocalDate(dayIso) {
  const [y, m, d] = dayIso.split("-").map(Number);
  const date = new Date(y, m - 1, d, 12, 0, 0, 0);
  const dow = date.getDay();
  const mondayOffset = dow === 0 ? -6 : 1 - dow;
  date.setDate(date.getDate() + mondayOffset);
  return toYmd(date);
}

/** @param {string} iso @param {number} delta calendar days */
export function addCalendarDaysIso(iso, delta) {
  const [y, m, d] = iso.split("-").map(Number);
  const date = new Date(y, m - 1, d, 12, 0, 0, 0);
  date.setDate(date.getDate() + delta);
  return toYmd(date);
}

export function diffDaysBetweenIso(aIso, bIso) {
  const [ya, ma, da] = aIso.split("-").map(Number);
  const [yb, mb, db] = bIso.split("-").map(Number);
  const a = Date.UTC(ya, ma - 1, da);
  const b = Date.UTC(yb, mb - 1, db);
  return Math.round((b - a) / 86400000);
}

/** @param {string} mondayIso @param {string} dayIso @returns {"mon"|"tue"|"wed"|"thu"|"fri"|"sat"|"sun"|null} */
export function weekdayKeyFromMonday(mondayIso, dayIso) {
  const diff = diffDaysBetweenIso(mondayIso, dayIso);
  if (diff < 0 || diff > 6) {
    return null;
  }

  /** @type {typeof WEEKDAYS[number]} */
  const key = WEEKDAYS[diff];
  return key;
}

/** ISO week number (1–53) for a date in local midday. */
export function isoWeekNumber(dayIso) {
  const [y, m, d] = dayIso.split("-").map(Number);
  const date = new Date(y, m - 1, d, 12, 0, 0, 0);
  const targetThursday = new Date(date);
  targetThursday.setDate(date.getDate() + (4 - ((date.getDay() + 6) % 7)));
  const yearStart = new Date(targetThursday.getFullYear(), 0, 1);
  const weekNumber = Math.ceil(
    ((targetThursday - yearStart) / 86400000 + ((yearStart.getDay() + 6) % 7) + 1) / 7,
  );
  return Math.max(1, weekNumber);
}

export function shiftWeekKeepingOffset(selectedIsoDate, mondayIsoBefore, deltaWeeks) {
  const offset = diffDaysBetweenIso(mondayIsoBefore, selectedIsoDate);
  const nextMonday = addCalendarDaysIso(mondayIsoBefore, deltaWeeks * 7);
  const clampedOffset = Math.max(0, Math.min(6, offset));
  return addCalendarDaysIso(nextMonday, clampedOffset);
}

export function monthFirstIso(dayIso) {
  const [y, m] = dayIso.split("-").map(Number);
  return `${String(y).padStart(4, "0")}-${String(m).padStart(2, "0")}-01`;
}

export function addMonthsIso(firstOfMonthIso, delta) {
  const [y, m] = firstOfMonthIso.split("-").map(Number);
  const date = new Date(y, m - 1 + delta, 1, 12, 0, 0, 0);
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-01`;
}

export function daysInMonthYm(firstIso) {
  const [y, m] = firstIso.split("-").map(Number);
  return new Date(y, m, 0).getDate();
}
