const DAY = 86_400_000;
function stamp(value: string): number {
  const [year, month, day] = value.split('-').map(Number);
  return Date.UTC(year, month - 1, day);
}
export function isDate(value: unknown): value is string {
  if (typeof value !== 'string' || !/^(19|20|21)\d{2}-\d{2}-\d{2}$/.test(value)) return false;
  const time = stamp(value); return Number.isFinite(time) && new Date(time).toISOString().slice(0, 10) === value;
}
export function addDays(value: string, count: number): string {
  if (!isDate(value) || !Number.isSafeInteger(count)) throw new Error('Invalid date');
  return new Date(stamp(value) + count * DAY).toISOString().slice(0, 10);
}
export function calendarDays(start: string, end: string): number {
  if (!isDate(start) || !isDate(end) || end < start) throw new Error('Invalid date range');
  return Math.round((stamp(end) - stamp(start)) / DAY) + 1;
}
export function workingDays(start: string, end: string): number {
  const count = calendarDays(start, end); let total = Math.floor(count / 7) * 5;
  const weekday = new Date(stamp(start)).getUTCDay();
  for (let index = 0; index < count % 7; index++) if (![0, 6].includes((weekday + index) % 7)) total++;
  return total;
}
export function nextWorkingDay(value: string): string {
  let next = addDays(value, 1);
  while ([0, 6].includes(new Date(stamp(next)).getUTCDay())) next = addDays(next, 1);
  return next;
}
