import type { ContactCard, PartialDate } from "@/lib/jmap/types"; import { getContactDisplayName, getContactPhotoUri } from "@/stores/contact-store"; function escapeHtml(value: string): string { return value .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } export function printContact(contact: ContactCard, displayName?: string): void { const printWindow = window.open("", "_blank"); if (!printWindow) return; const name = displayName || getContactDisplayName(contact); const photoUri = getContactPhotoUri(contact); const emails = contact.emails ? Object.values(contact.emails) : []; const phones = contact.phones ? Object.values(contact.phones) : []; const orgs = contact.organizations ? Object.values(contact.organizations) : []; const titles = contact.titles ? Object.values(contact.titles) : []; const addresses = contact.addresses ? Object.values(contact.addresses) : []; const onlineServices = contact.onlineServices ? Object.values(contact.onlineServices) : []; const notes = contact.notes ? Object.values(contact.notes) : []; const anniversaries = contact.anniversaries ? Object.values(contact.anniversaries) : []; const rows: string[] = []; const section = (title: string, items: string[]) => { if (items.length === 0) return; rows.push(`

${escapeHtml(title)}

${items.join("")}
`); }; const row = (label: string, value: string) => `
${escapeHtml(label)}
${escapeHtml(value)}
`; section("Email", emails.map(e => row(e.label || "Email", e.address || ""))); section("Phone", phones.map(p => row(p.label || "Phone", p.number || ""))); section( "Organization", orgs.map(o => { const units = o.units ? Object.values(o.units).map(u => u.name).filter(Boolean).join(", ") : ""; const value = [o.name, units].filter(Boolean).join(" \u2014 "); return row("Organization", value); }), ); section("Title", titles.map(t => row(t.kind === "role" ? "Role" : "Title", t.name || ""))); section( "Address", addresses.map(a => { const parts = [a.street, a.locality, a.region, a.postcode, a.country] .map(p => (typeof p === "string" ? p : "")) .filter(Boolean); return row(a.label || "Address", parts.join(", ")); }), ); section( "Online", onlineServices.map(s => row(s.label || s.service || "Online", s.uri || s.user || "")), ); section( "Anniversary", anniversaries.map(a => { const date = a.date; let formatted = ""; if (typeof date === "object" && date !== null) { if ("utc" in date && typeof date.utc === "string") formatted = date.utc; else { const parts: string[] = []; const pd = date as PartialDate; if (pd.year) parts.push(String(pd.year)); if (pd.month) parts.push(String(pd.month).padStart(2, "0")); if (pd.day) parts.push(String(pd.day).padStart(2, "0")); formatted = parts.join("-"); } } else if (date) { formatted = String(date); } return row(a.kind || "Date", formatted); }), ); section("Notes", notes.map(n => row("", n.note || ""))); const photoTag = photoUri ? `` : `
${escapeHtml((name || "?").charAt(0).toUpperCase())}
`; const html = ` ${escapeHtml(name || "Contact")}
${photoTag}

${escapeHtml(name || "Contact")}

${rows.join("")} `; printWindow.document.write(html); printWindow.document.close(); printWindow.focus(); printWindow.print(); }