export default function parseAbsence(str, teacherMap) { const LAST_HOUR = 10; const s = (str ?? "").trim().replace(/\s+/g, " "); const result = { teacher: null, // String or null teacherCode: null, // String or null type: null, // "wholeDay" | "range" | "single" | "invalid" hours: null // { from, to } or number }; if (!s) { result.type = "invalid"; result.original = s; return result; } const isTeacher = (t) => /^[A-Za-z]+$/.test(t); const parseSpec = (spec) => { let m; // "5+" -> range 5..LAST_HOUR if ((m = spec.match(/^(\d+)\+$/))) { const from = parseInt(m[1], 10); if (from >= 1 && from <= LAST_HOUR) { return { kind: "range", value: { from, to: LAST_HOUR } }; } return null; } // "5-7" -> range 5..7 if ((m = spec.match(/^(\d+)-(\d+)$/))) { const from = parseInt(m[1], 10); const to = parseInt(m[2], 10); if (from >= 1 && to >= 1 && from <= to && to <= LAST_HOUR) { return { kind: "range", value: { from, to } }; } return null; } // "5" -> single 5 if ((m = spec.match(/^(\d+)$/))) { const hour = parseInt(m[1], 10); if (hour >= 1 && hour <= LAST_HOUR) { return { kind: "single", value: hour }; } return null; } return null; }; const parts = s.split(" "); if (parts.length === 1) { const t = parts[0]; if (isTeacher(t)) { result.teacherCode = t; result.teacher = teacherMap?.[t.toLowerCase()] ?? null; result.type = "wholeDay"; return result; } result.type = "invalid"; result.original = s; return result; } if (parts.length === 2) { const [a, b] = parts; // Teacher first: "Nm 5", "Nm 5-7", "Nm 5+" if (isTeacher(a)) { const spec = parseSpec(b); if (!spec) { result.type = "invalid"; result.original = s; return result; } result.teacherCode = a; result.teacher = teacherMap?.[a.toLowerCase()] ?? null; result.type = spec.kind === "range" ? "range" : "single"; result.hours = spec.value; return result; } // Teacher last: "5 Nm", "5-7 Nm", "5+ Nm" if (isTeacher(b)) { const spec = parseSpec(a); if (!spec) { result.type = "invalid"; result.original = s; return result; } result.teacherCode = b; result.teacher = teacherMap?.[b.toLowerCase()] ?? null; result.type = spec.kind === "range" ? "range" : "single"; result.hours = spec.value; return result; } result.type = "invalid"; result.original = s; return result; } // Anything else is invalid result.type = "invalid"; result.original = s; return result; }