import { NextResponse } from 'next/server'; import { prisma } from '@/lib/prisma'; export async function GET(req: Request, { params }: { params: { id: string } }) { try { const { id } = params; const order = await prisma.order.findUnique({ where: { id }, include: { items: true }, }); if (!order) { return NextResponse.json({ error: 'Order not found' }, { status: 404 }); } const item = order.items[0]; if (!item) { return NextResponse.json({ error: 'No items in order' }, { status: 400 }); } let design: { front: any[]; back: any[] } = { front: [], back: [] }; try { design = JSON.parse(item.designJson) as { front: any[]; back: any[] }; } catch (e) { console.error('Error parsing designJson:', e); // Continue with empty design } const product = await prisma.product.findUnique({ where: { id: item.productId }, }); if (!product) { return NextResponse.json({ error: 'Product not found' }, { status: 404 }); } // Generate HTML/CSS for a printable spec sheet const printAreaWidthMm = product.printAreaWidthMm || 200; const printAreaHeightMm = product.printAreaHeightMm || 280; // Calculate scale factor: pixels to millimeters const DISPLAY = 560; // Same as in DesignCanvas const printArea = JSON.parse(product.printArea) as { xPct: number; yPct: number; wPct: number; hPct: number; }; const printAreaStartX = DISPLAY * printArea.xPct; const printAreaStartY = DISPLAY * printArea.yPct; const printAreaWidthPx = DISPLAY * printArea.wPct; const printAreaHeightPx = DISPLAY * printArea.hPct; // Scale: how many centimeters per pixel // printAreaWidthMm / printAreaWidthPx = mm/px // Then divide by 10 to get cm/px const cmPerPx = (printAreaWidthMm / printAreaWidthPx) / 10; // Convert pixel measurements to CM const convertToCm = (px: number) => { return (px * cmPerPx).toFixed(1); }; // Convert element position (subtract offset first, then scale) const convertPositionToCm = (elementPx: number, offsetPx: number) => { const relativeToStart = Math.max(0, elementPx - offsetPx); return (relativeToStart * cmPerPx).toFixed(1); }; const generateDesignSection = (designElements: any[], side: 'Front' | 'Back', placement: string | null, designPreview: string | null) => { // Always show the section if we have preview images, even without elements if ((!designElements || designElements.length === 0) && !placement && !designPreview) return ''; return `

${side} Design

${designElements && designElements.length > 0 ? ` ` : ''} ${designPreview ? `

Design preview (transparent background)

${side} design preview
` : ''} ${placement ? `

Design on product with measurement guides

${side} design placement ${Array.from({ length: Math.ceil((DISPLAY / (10 * (printAreaWidthMm / 100)))) }).map((_, i) => { const cm = i * 2; const px = (cm * DISPLAY) / (printAreaWidthMm / 10); if (px > DISPLAY) return ''; return ` ${cm}cm ${cm} `; }).join('')} X (0cm) Y (0cm) ${designElements.map((el, idx) => ` E${idx + 1} `).join('')}

━━ Red dashed line: Print area boundary

━ Blue line: X-axis (horizontal, 0cm at left edge)

━ Green line: Y-axis (vertical, 0cm at top edge)

┊ Brown dashed lines: Position guides from edges to element center

T: / L: Distance from top and left edges of garment in cm

● Orange circles: Design element positions (E1, E2, etc.)

` : ''} ${designElements && designElements.length > 0 ? ` ${designElements.map((el, idx) => ` `).join('')}
Element Type Position (CM) Position (px) Size (CM) Size (px) Details
E${idx + 1} ${el.type === 'text' ? '📝 Text' : '🖼️ Image'} X: ${convertPositionToCm(el.x, printAreaStartX)} | Y: ${convertPositionToCm(el.y, printAreaStartY)} X: ${Math.round(el.x - printAreaStartX)} | Y: ${Math.round(el.y - printAreaStartY)} ${el.type === 'image' ? `${convertToCm(el.width)} × ${convertToCm(el.height)}` : 'N/A'} ${el.type === 'image' ? `${Math.round(el.width)} × ${Math.round(el.height)}` : 'N/A'} ${el.type === 'text' ? ` Font: ${el.fontFamily}, ${Math.round(el.fontSize * cmPerPx * 2.834)}pt
Color: ${el.fill}
Text: "${el.text}"
Rotation: ${Math.round(el.rotation)}° ` : ` Rotation: ${Math.round(el.rotation)}° `}
` : `

No individual design elements to measure.

`}
`; }; const html = ` Design Specification - Order ${order.id}

Design Specification Sheet

Order ID: ${order.id}

Product: ${item.productName}

Color: ${item.color} ${item.size ? `| Size: ${item.size}` : ''}

${item.designWidthCm && item.designHeightCm ? `

Design Dimensions (Overall): ${item.designWidthCm} cm × ${item.designHeightCm} cm

` : ''} ${item.designImageDimensions ? (() => { try { const imageDims = JSON.parse(item.designImageDimensions); return imageDims && imageDims.length > 0 ? `

Image Dimensions:

` : ''; } catch (e) { return ''; } })() : ''}

Order Date: ${new Date(order.createdAt).toLocaleDateString()}

${generateDesignSection(design.front, 'Front', item.placementPreviewUrl, item.designPreviewUrl)} ${generateDesignSection(design.back, 'Back', item.placementPreviewUrlBack, item.designPreviewUrlBack)}

Notes:

`; return new NextResponse(html, { headers: { 'Content-Type': 'text/html; charset=utf-8', 'Content-Disposition': `attachment; filename="design-spec-${order.id}.html"`, }, }); } catch (err) { console.error('Error generating design spec:', err); return NextResponse.json({ error: 'Failed to generate specification' }, { status: 500 }); } }