import { DateTime } from 'luxon';

const HH_MM = 'HH:mm';

/**
 * Builds a [start, end) DateTime range from two HH:MM strings.
 * Handles night shifts: if end <= start, end is treated as the next day.
 * No timezone or DST concerns — both endpoints are wall-clock-only.
 */
function buildRange(start: string, end: string): [DateTime, DateTime] {
    const s = DateTime.fromFormat(start, HH_MM);
    let e = DateTime.fromFormat(end, HH_MM);
    if (e <= s) e = e.plus({ days: 1 });
    return [s, e];
}

/**
 * Returns true iff the two HH:MM ranges overlap. Handles night-shift wraparound.
 * Half-open semantics: a range that ends exactly when another starts does NOT overlap.
 */
export function hasTimeOverlap(s1: string, e1: string, s2: string, e2: string): boolean {
    const [a1, b1] = buildRange(s1, e1);
    const [a2, b2] = buildRange(s2, e2);
    return a1 < b2 && a2 < b1;
}

/**
 * Parses an HH:MM string into minutes since 00:00.
 */
export function toMinutes(hhmm: string): number {
    const [h, m] = hhmm.split(':').map((p) => parseInt(p, 10));
    return h * 60 + m;
}

/**
 * Half-open numeric interval overlap check. Returns true iff [aStart, aEnd) and [bStart, bEnd) overlap.
 */
export function intervalsOverlap(aStart: number, aEnd: number, bStart: number, bEnd: number): boolean {
    return aStart < bEnd && bStart < aEnd;
}

const MINUTES_PER_DAY = 24 * 60;

/**
 * Duration in hours of a single HH:MM time slot. Handles midnight crossing
 * (end time at or before start time is treated as next-day).
 */
export function timeSlotHours(startTime: string, endTime: string): number {
    const start = toMinutes(startTime);
    const rawEnd = toMinutes(endTime);
    const end = rawEnd <= start ? rawEnd + MINUTES_PER_DAY : rawEnd;
    return (end - start) / 60;
}
