/** Agency scheduling helpers for creative_pipeline. */ export const PUBLISH_CHANNELS = ['instagram', 'facebook'] as const; export type PublishChannel = (typeof PUBLISH_CHANNELS)[number]; export const PUBLISH_STATUSES = [ 'idle', 'queued', 'publishing', 'published', 'failed', ] as const; export type PublishStatus = (typeof PUBLISH_STATUSES)[number]; export function normalizeChannels(raw: unknown): PublishChannel[] { const list = Array.isArray(raw) ? raw.map((x) => String(x).toLowerCase().trim()) : typeof raw === 'string' ? raw.split(',').map((x) => x.toLowerCase().trim()) : []; const out = PUBLISH_CHANNELS.filter((c) => list.includes(c)); return out.length ? [...out] : ['instagram', 'facebook']; } /** Parse datetime-local or ISO into timestamptz ISO, or null to clear. */ export function parseScheduledAt(raw: unknown): string | null | undefined { if (raw === null) return null; if (raw === undefined) return undefined; if (typeof raw !== 'string') return undefined; const t = raw.trim(); if (!t) return null; const d = new Date(t); if (Number.isNaN(d.getTime())) return undefined; return d.toISOString(); } export function toDatetimeLocalValue(iso?: string | null): string { if (!iso) return ''; const d = new Date(iso); if (Number.isNaN(d.getTime())) return ''; const pad = (n: number) => String(n).padStart(2, '0'); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`; } export function scheduleLabel(iso?: string | null): string | null { if (!iso) return null; const d = new Date(iso); if (Number.isNaN(d.getTime())) return null; return d.toLocaleString('es-ES', { weekday: 'short', day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit', }); }