import type { MarginPreset, PageId } from "../engine/geometry"; /** Page and template choices frozen with an invoice at issue (stored as JSON). */ export interface RenderPrefsV1 { version: 1; templateId: string; pageSize: PageId; margins: MarginPreset; logo?: { /** The logo already contains the business name, so a template drops its own name lockup. */ useWordmark?: boolean; }; } export const DEFAULT_PREFS: RenderPrefsV1 = { version: 1, templateId: "classic", pageSize: "A4", margins: "template", }; const PAGE_SIZE_IDS: readonly PageId[] = ["A4", "LETTER"]; const MARGIN_IDS: readonly MarginPreset[] = ["template", "narrow", "normal"]; /** Tolerant: anything unreadable or out of range falls back to the default for that field. */ export function parsePrefs(json: string | null | undefined): RenderPrefsV1 { if (!json) return { ...DEFAULT_PREFS }; let raw: unknown; try { raw = JSON.parse(json); } catch { return { ...DEFAULT_PREFS }; } if (typeof raw !== "object" || raw === null) return { ...DEFAULT_PREFS }; const o = raw as Record; const prefs: RenderPrefsV1 = { version: 1, templateId: typeof o.templateId === "string" && o.templateId ? o.templateId : DEFAULT_PREFS.templateId, pageSize: PAGE_SIZE_IDS.includes(o.pageSize as PageId) ? (o.pageSize as PageId) : DEFAULT_PREFS.pageSize, margins: MARGIN_IDS.includes(o.margins as MarginPreset) ? (o.margins as MarginPreset) : DEFAULT_PREFS.margins, }; const logo = o.logo; if (typeof logo === "object" && logo !== null && typeof (logo as { useWordmark?: unknown }).useWordmark === "boolean") { prefs.logo = { useWordmark: (logo as { useWordmark: boolean }).useWordmark }; } return prefs; } export const prefsToJson = (prefs: RenderPrefsV1): string => JSON.stringify(prefs);