// src/dates/format.ts
import { DateTime } from "luxon";
import { DateTime as DateTime2, Duration, Interval } from "luxon";
function utcNow() {
  return DateTime.now().toUTC();
}
function parseDateTime(value, zone) {
  if (typeof value === "string") {
    const dt = DateTime.fromISO(value, { zone: zone ?? "utc" });
    if (!dt.isValid) {
      throw new RangeError(`Invalid DateTime string "${value}": ${dt.invalidReason ?? "unknown error"}`);
    }
    return dt;
  }
  if (!value.isValid) {
    throw new RangeError(`Invalid DateTime: ${value.invalidReason ?? "unknown error"}`);
  }
  return value;
}
function formatIso8601(dt) {
  const parsed = parseDateTime(dt);
  const iso = parsed.toUTC().toISO({
    suppressMilliseconds: false,
    includeOffset: false
  });
  return `${iso}Z`;
}
// src/dates/interval.ts
import { Interval as Interval2 } from "luxon";
function scheduleDateInterval(start, end) {
  const startDt = parseDateTime(start);
  const endDt = parseDateTime(end);
  if (endDt < startDt) {
    throw new RangeError(`Interval end (${endDt.toISO()}) is before start (${startDt.toISO()})`);
  }
  return Interval2.fromDateTimes(startDt, endDt);
}
function isDstTransition(date, zone) {
  let dt;
  try {
    dt = parseDateTime(date);
  } catch {
    return false;
  }
  const inZone = dt.setZone(zone);
  if (!inZone.isValid)
    return false;
  const startOfDay = inZone.startOf("day");
  const nextMidnight = startOfDay.plus({ days: 1 });
  return startOfDay.offset !== nextMidnight.offset;
}
function validateConnectionTime(arrival, departure, options) {
  const arrivalDt = parseDateTime(arrival);
  const departureDt = parseDateTime(departure);
  const minMinutes = options?.minMinutes ?? 30;
  const maxMinutes = options?.maxMinutes ?? 240;
  const diffMs = departureDt.toMillis() - arrivalDt.toMillis();
  const connectionMinutes = Math.round(diffMs / 60000);
  if (connectionMinutes < minMinutes) {
    return {
      valid: false,
      connectionMinutes,
      reason: `Connection too short: ${connectionMinutes} minutes, minimum is ${minMinutes}`
    };
  }
  if (connectionMinutes > maxMinutes) {
    return {
      valid: false,
      connectionMinutes,
      reason: `Connection too long: ${connectionMinutes} minutes, maximum is ${maxMinutes}`
    };
  }
  return { valid: true, connectionMinutes };
}
function elapsedMinutes(from, to) {
  const fromDt = parseDateTime(from);
  const toDt = parseDateTime(to);
  return toDt.diff(fromDt, "minutes").minutes;
}
// src/dates/timezone.ts
var AU_TIMEZONES = {
  SYDNEY: "Australia/Sydney",
  MELBOURNE: "Australia/Melbourne",
  BRISBANE: "Australia/Brisbane",
  PERTH: "Australia/Perth",
  ADELAIDE: "Australia/Adelaide",
  DARWIN: "Australia/Darwin",
  EUCLA: "Australia/Eucla",
  HOBART: "Australia/Hobart",
  LINDEMAN: "Australia/Lindeman"
};
var AIRPORT_TIMEZONE_MAP = {
  SYD: "Australia/Sydney",
  MEL: "Australia/Melbourne",
  BNE: "Australia/Brisbane",
  PER: "Australia/Perth",
  ADL: "Australia/Adelaide",
  DRW: "Australia/Darwin",
  CNS: "Australia/Brisbane",
  CBR: "Australia/Sydney",
  HBA: "Australia/Hobart",
  OOL: "Australia/Brisbane",
  NTL: "Australia/Sydney",
  MCY: "Australia/Brisbane",
  ASP: "Australia/Darwin",
  TSV: "Australia/Brisbane",
  AVV: "Australia/Melbourne",
  ROK: "Australia/Brisbane",
  JAD: "Australia/Perth",
  GET: "Australia/Perth",
  KNX: "Australia/Perth",
  HTI: "Australia/Lindeman",
  PPP: "Australia/Lindeman",
  MKY: "Australia/Brisbane",
  AKL: "Pacific/Auckland",
  WLG: "Pacific/Auckland",
  CHC: "Pacific/Auckland",
  LAX: "America/Los_Angeles",
  SFO: "America/Los_Angeles",
  JFK: "America/New_York",
  LGA: "America/New_York",
  ORD: "America/Chicago",
  DFW: "America/Chicago",
  ATL: "America/New_York",
  MIA: "America/New_York",
  SEA: "America/Los_Angeles",
  DEN: "America/Denver",
  IAH: "America/Chicago",
  BOS: "America/New_York",
  WAS: "America/New_York",
  LHR: "Europe/London",
  LGW: "Europe/London",
  MAN: "Europe/London",
  CDG: "Europe/Paris",
  FRA: "Europe/Berlin",
  MUC: "Europe/Berlin",
  AMS: "Europe/Amsterdam",
  FCO: "Europe/Rome",
  MXP: "Europe/Rome",
  ZRH: "Europe/Zurich",
  MAD: "Europe/Madrid",
  BCN: "Europe/Madrid",
  CPH: "Europe/Copenhagen",
  ARN: "Europe/Stockholm",
  OSL: "Europe/Oslo",
  HEL: "Europe/Helsinki",
  DUB: "Europe/Dublin",
  NRT: "Asia/Tokyo",
  HND: "Asia/Tokyo",
  KIX: "Asia/Tokyo",
  ICN: "Asia/Seoul",
  HKG: "Asia/Hong_Kong",
  SIN: "Asia/Singapore",
  BKK: "Asia/Bangkok",
  KUL: "Asia/Kuala_Lumpur",
  MNL: "Asia/Manila",
  DPS: "Asia/Makassar",
  CGK: "Asia/Jakarta",
  PVG: "Asia/Shanghai",
  PEK: "Asia/Shanghai",
  CAN: "Asia/Shanghai",
  DEL: "Asia/Kolkata",
  BOM: "Asia/Kolkata",
  DXB: "Asia/Dubai",
  AUH: "Asia/Dubai",
  DOH: "Asia/Qatar",
  AMM: "Asia/Amman",
  RUH: "Asia/Riyadh",
  JED: "Asia/Riyadh",
  YYZ: "America/Toronto",
  YVR: "America/Vancouver",
  YUL: "America/Montreal",
  MEX: "America/Mexico_City",
  GRU: "America/Sao_Paulo",
  GIG: "America/Sao_Paulo",
  EZE: "America/Argentina/Buenos_Aires",
  SCL: "America/Santiago",
  LIM: "America/Lima",
  JNB: "Africa/Johannesburg",
  CPT: "Africa/Johannesburg",
  CAI: "Africa/Cairo",
  NBO: "Africa/Nairobi",
  LOS: "Africa/Lagos"
};
function isAustralianZone(zone) {
  return Object.values(AU_TIMEZONES).includes(zone);
}
function airportTimezone(code) {
  return AIRPORT_TIMEZONE_MAP[code.toUpperCase()];
}
function zonedDateTime(dt, zone) {
  if (!dt.isValid) {
    throw new RangeError("Cannot create ZonedDateTime from an invalid DateTime");
  }
  return { datetime: dt, zone: zone ?? dt.zoneName ?? "UTC" };
}
export {
  zonedDateTime,
  validateConnectionTime,
  utcNow,
  scheduleDateInterval,
  parseDateTime,
  isDstTransition,
  isAustralianZone,
  formatIso8601,
  elapsedMinutes,
  airportTimezone,
  Interval,
  Duration,
  DateTime2 as DateTime,
  AU_TIMEZONES,
  AIRPORT_TIMEZONE_MAP
};
