import { NextRequest, NextResponse } from 'next/server'; import { db } from '@/lib/db'; import { getCookieToken, getSessionUser } from '@/lib/auth'; import { logActivity } from '@/lib/activity'; function escapeCsvField(value: unknown): string { const str = value === null || value === undefined ? '' : String(value); if (str.includes(',') || str.includes('"') || str.includes('\n')) { return `"${str.replace(/"/g, '""')}"`; } return str; } export async function GET(request: NextRequest) { try { const token = getCookieToken(request); if (!token) { return NextResponse.json({ error: 'Not authenticated' }, { status: 401 }); } const user = await getSessionUser(token); if (!user) { return NextResponse.json({ error: 'Not authenticated' }, { status: 401 }); } const invoices = await db.invoice.findMany({ where: { userId: user.id }, orderBy: { createdAt: 'desc' }, }); const headers = [ 'ID', 'Filename', 'Vendor', 'Invoice Number', 'Invoice Date', 'Due Date', 'Subtotal', 'VAT Amount', 'Total', 'Currency', 'Status', 'Duplicate', 'Confidence', 'Created At', ]; const rows = invoices.map((inv) => [ inv.id, inv.filename ?? '', inv.vendor ?? '', inv.invNumber ?? '', inv.invDate ?? '', inv.dueDate ?? '', inv.amount ?? '', inv.vatAmount ?? '', inv.total ?? '', inv.currency, inv.status, inv.isDuplicate ? 'Yes' : 'No', inv.confidence !== null ? (inv.confidence * 100).toFixed(1) + '%' : '', inv.createdAt.toISOString(), ].map(escapeCsvField).join(',') ); const csvContent = [ headers.map(escapeCsvField).join(','), ...rows, ].join('\n'); const timestamp = new Date().toISOString().split('T')[0]; logActivity(user.id, 'export', 'CSV exported', 'Exported all invoices as CSV'); return new NextResponse(csvContent, { status: 200, headers: { 'Content-Type': 'text/csv; charset=utf-8', 'Content-Disposition': `attachment; filename="invoices-${timestamp}.csv"`, }, }); } catch (error) { console.error('[EXPORT_CSV_ERROR]', error); return NextResponse.json( { error: 'Internal server error' }, { status: 500 } ); } }