import { composeShareImage, copyText, detectShareCapability, downloadShareImage, openShareSheet, shareFile, type ShareMetadata, } from '../share'; export type ShareOutcome = 'shared' | 'downloaded' | 'copied' | 'dismissed' | 'failed'; export interface ShareRequest { image: string; filename: string; title: string; url?: string; merchantName?: string; productImage?: string; } export function tryOnFilename(productTitle?: string, at: number = Date.now()): string { const slug = productTitle ? productTitle.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') : ''; return `virtual-tryon-${slug || 'result'}-${at}.png`; } function absoluteUrl(url: string): string { try { return new URL(url, window.location.href).href; } catch { return url; } } /** Gallery exports use the same branded compositor; the stored raw render is never handed off. */ export async function shareTryOn({ image, title, url, merchantName, productImage }: ShareRequest): Promise { const productUrl = url ? absoluteUrl(url) : null; const metadata: ShareMetadata = { itemName: title, productUrl, brandName: merchantName, productImage }; let blob: Blob; try { blob = await composeShareImage(image, metadata); } catch { return 'failed'; } const file = shareFile(blob); const capability = detectShareCapability(file, navigator, metadata); if (capability === 'file_share') { const copyPromise = productUrl ? copyText(productUrl) : Promise.resolve(false); const resultPromise = openShareSheet(file, metadata); const [, result] = await Promise.all([copyPromise, resultPromise]); if (result.outcome === 'share_sheet_closed') return 'shared'; if (result.outcome === 'cancelled') return 'dismissed'; } try { downloadShareImage(blob); if (productUrl) void copyText(productUrl); return 'downloaded'; } catch { if (productUrl && await copyText(productUrl)) return 'copied'; return 'failed'; } }