export function makeId(prefix) { return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; } export function todayYMD() { const now = new Date(); return `${now.getFullYear()}-${`${now.getMonth() + 1}`.padStart(2, '0')}-${`${now.getDate()}`.padStart(2, '0')}`; } export function parseYMD(value) { if (!value || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return null; const d = new Date(`${value}T00:00:00`); return Number.isNaN(d.getTime()) ? null : d; } export function findActiveTripId(trips) { const today = parseYMD(todayYMD()); if (!today) return null; const active = trips.find((trip) => { const start = parseYMD(trip.startDate); const end = parseYMD(trip.endDate); return !!start && !!end && today >= start && today <= end; }); return active?.id || null; } export function findNextTripId(trips) { const today = parseYMD(todayYMD()); if (!today) return null; const next = trips .map((trip) => ({ id: trip.id, start: parseYMD(trip.startDate) })) .filter((trip) => !!trip.start && trip.start >= today) .sort((a, b) => a.start - b.start)[0]; return next?.id || null; } export function findBestTripId(trips) { const activeTripId = findActiveTripId(trips); if (activeTripId) return activeTripId; const nextTripId = findNextTripId(trips); if (nextTripId) return nextTripId; const latestPast = trips .map((trip) => ({ id: trip.id, end: parseYMD(trip.endDate), start: parseYMD(trip.startDate) })) .filter((trip) => !!trip.end || !!trip.start) .sort((a, b) => { const aTime = (a.end || a.start).getTime(); const bTime = (b.end || b.start).getTime(); return bTime - aTime; })[0]; return latestPast?.id || null; }