// Date utilities — Monday-start week, 24h, ISO date strings.

const MONTH_NAMES = ["January","February","March","April","May","June","July","August","September","October","November","December"];
const MONTH_SHORT = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
const DOW_LONG = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
const DOW_SHORT = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
const DOW_NARROW = ["M","T","W","T","F","S","S"];

// dateKey from a Date
const keyOf = (date) => {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
};

const parseKey = (k) => {
  const [y, m, d] = k.split("-").map(Number);
  return new Date(y, m - 1, d);
};

const addDays = (date, n) => {
  const d = new Date(date);
  d.setDate(d.getDate() + n);
  return d;
};

const addMonths = (date, n) => {
  const d = new Date(date.getFullYear(), date.getMonth() + n, 1);
  return d;
};

const sameDay = (a, b) => keyOf(a) === keyOf(b);

// Monday=0, Sunday=6
const dowMon = (date) => (date.getDay() + 6) % 7;

// Build a 6x7 grid of Dates for a given (year, month0), aligned Mon..Sun.
function monthGrid(year, month0) {
  const first = new Date(year, month0, 1);
  const offset = dowMon(first);
  const start = addDays(first, -offset);
  const cells = [];
  for (let i = 0; i < 42; i++) cells.push(addDays(start, i));
  return cells;
}

// Get events that touch a given date key (handles multi-day via endDate).
function eventsOnDate(events, key) {
  return events.filter((e) => {
    if (!e.endDate) return e.date === key;
    return e.date <= key && key <= e.endDate;
  });
}

// Sort events: all-day first, then by start time.
function sortEvents(evts) {
  return [...evts].sort((a, b) => {
    if (a.allDay && !b.allDay) return -1;
    if (!a.allDay && b.allDay) return 1;
    return (a.start || "").localeCompare(b.start || "");
  });
}

// Shorten a title for tight cells
function clipTitle(t, n) {
  if (t.length <= n) return t;
  return t.slice(0, n - 1) + "…";
}

// Format a date for headers
const fmtLong = (date) => `${DOW_LONG[dowMon(date)]}, ${date.getDate()} ${MONTH_NAMES[date.getMonth()]}`;
const fmtMonthYear = (date) => `${MONTH_NAMES[date.getMonth()]} ${date.getFullYear()}`;

window.CAL_UTILS = {
  MONTH_NAMES, MONTH_SHORT, DOW_LONG, DOW_SHORT, DOW_NARROW,
  keyOf, parseKey, addDays, addMonths, sameDay, dowMon,
  monthGrid, eventsOnDate, sortEvents, clipTitle,
  fmtLong, fmtMonthYear,
};
