// Shared schedule rule helpers for playlist playback and editor rendering. const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; function normalizeDateTimeValue(value) { const raw = String(value || '').trim(); return raw ? raw : null; } function normalizeTimeValue(value) { const raw = String(value || '').trim(); if (!raw) { return null; } const match = raw.match(/^(\d{2}):(\d{2})(?::\d{2})?$/); if (!match) { return null; } return match[1] + ':' + match[2]; } function normalizeDayValues(value) { let days = []; if (Array.isArray(value)) { days = value; } else if (value !== undefined && value !== null && String(value).trim()) { try { const parsed = typeof value === 'string' ? JSON.parse(value) : value; if (Array.isArray(parsed)) { days = parsed; } } catch (_error) { days = String(value) .split(',') .map(function (item) { return item.trim(); }) .filter(Boolean); } } return Array.from(new Set(days.map(function (day) { return Number(day); }).filter(function (day) { return Number.isInteger(day) && day >= 0 && day <= 6; }))).sort(function (left, right) { return left - right; }); } function normalizeScheduleRule(rule) { const input = rule && typeof rule === 'object' ? rule : {}; const startDatetime = normalizeDateTimeValue( input.start_datetime || input.startDateTime || input.schedule_start_datetime || input.scheduleStartDatetime ); const endDatetime = normalizeDateTimeValue( input.end_datetime || input.endDateTime || input.schedule_end_datetime || input.scheduleEndDatetime ); const startTime = normalizeTimeValue( input.start_time || input.startTime || input.schedule_start_time || input.scheduleStartTime ); const endTime = normalizeTimeValue( input.end_time || input.endTime || input.schedule_end_time || input.scheduleEndTime ); const days = normalizeDayValues( input.days || input.day_list || input.schedule_days || input.schedule_days_json || input.scheduleDays ); if (startDatetime || endDatetime) { if (!startDatetime || !endDatetime) { return null; } } if (startTime || endTime) { if (!startTime || !endTime) { return null; } } if (!startDatetime && !endDatetime && !startTime && !endTime && !days.length) { return null; } const normalized = {}; if (startDatetime) { normalized.start_datetime = startDatetime; } if (endDatetime) { normalized.end_datetime = endDatetime; } if (startTime) { normalized.start_time = startTime; } if (endTime) { normalized.end_time = endTime; } if (days.length) { normalized.days = days; } return normalized; } function parseScheduleRules(value) { let rawRules = []; if (Array.isArray(value)) { rawRules = value; } else if (value && typeof value === 'object' && Array.isArray(value.rules)) { rawRules = value.rules; } else { const rawValue = String(value || '').trim(); if (!rawValue) { return []; } try { const parsed = JSON.parse(rawValue); rawRules = Array.isArray(parsed) ? parsed : []; } catch (_error) { return null; } } return rawRules .map(function (rule) { return normalizeScheduleRule(rule); }) .filter(Boolean); } function serializeScheduleRules(value) { const normalized = parseScheduleRules(value); if (normalized === null) { return null; } return JSON.stringify(normalized); } function formatDateTime(value) { const raw = String(value || '').trim(); if (!raw) { return ''; } return raw.replace('T', ' ').slice(0, 16); } function formatTime(value) { const raw = String(value || '').trim(); if (!raw) { return ''; } return raw.slice(0, 5); } function formatDays(value) { const days = normalizeDayValues(value); return days .map(function (day) { return DAY_NAMES[day] || ''; }) .filter(Boolean) .join(', '); } function formatScheduleRuleSummary(rule) { const normalized = normalizeScheduleRule(rule); if (!normalized) { return 'Always visible'; } const leftParts = []; if (normalized.start_datetime && normalized.end_datetime) { leftParts.push('Dates ' + formatDateTime(normalized.start_datetime) + ' to ' + formatDateTime(normalized.end_datetime)); } else { leftParts.push('Any date'); } const rightParts = []; const days = formatDays(normalized.days || []); if (days) { rightParts.push(days); } if (normalized.start_time && normalized.end_time) { rightParts.push(formatTime(normalized.start_time) + '-' + formatTime(normalized.end_time)); } if (rightParts.length) { return leftParts[0] + ': ' + rightParts.join(' '); } return leftParts[0]; } function formatScheduleRulesSummary(value) { const rules = parseScheduleRules(value) || []; if (!rules.length) { return 'Always visible'; } return rules.length === 1 ? '1 rule' : String(rules.length) + ' rules'; } module.exports = { normalizeDateTimeValue: normalizeDateTimeValue, normalizeTimeValue: normalizeTimeValue, normalizeDayValues: normalizeDayValues, normalizeScheduleRule: normalizeScheduleRule, parseScheduleRules: parseScheduleRules, serializeScheduleRules: serializeScheduleRules, formatScheduleRuleSummary: formatScheduleRuleSummary, formatScheduleRulesSummary: formatScheduleRulesSummary };