import { NextRequest, NextResponse } from 'next/server' import nodemailer from 'nodemailer' import { createClient } from '@supabase/supabase-js' export const dynamic = 'force-dynamic' export const runtime = 'nodejs' const createTransporter = () => { const smtpHost = process.env.SMTP_HOST const smtpPort = process.env.SMTP_PORT ? parseInt(process.env.SMTP_PORT, 10) : 587 const smtpUser = process.env.SMTP_USER?.trim() const smtpPassword = (process.env.SMTP_PASSWORD || '').replace(/\s/g, '').trim() const smtpFromEmail = process.env.SMTP_FROM_EMAIL || 'BUILDMATE ' const isPlaceholder = (smtpHost?.trim() === 'your_smtp_host') || (smtpUser === 'your_smtp_user') || (smtpPassword === 'your_smtp_password') if (isPlaceholder) { throw new Error('SMTP credentials are still placeholders. Please update .env.local.') } if (!smtpHost || !smtpUser || !smtpPassword) { throw new Error('SMTP credentials are missing in environment variables.') } const isGmail = smtpHost.toLowerCase().includes('gmail.com') const port = smtpPort || 587 const secure = port === 465 return nodemailer.createTransport({ host: smtpHost, port, secure, ...(isGmail && { requireTLS: true }), auth: { user: smtpUser, pass: smtpPassword }, }) } export async function POST(request: NextRequest) { try { const supabase = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL || '', process.env.SUPABASE_SERVICE_ROLE_KEY || '' ) const body = await request.json() const { title, content, featuredBuilds } = body if (!title || !content) { return NextResponse.json( { error: 'Title and content are required' }, { status: 400 } ) } // Get all users who opted in to newsletter const { data: preferences, error: prefsError } = await supabase .from('notification_preferences') .select('user_id') .eq('newsletter', true) if (prefsError) { console.error('Error fetching preferences:', prefsError) return NextResponse.json( { error: 'Failed to fetch preferences' }, { status: 500 } ) } if (!preferences || preferences.length === 0) { return NextResponse.json( { success: true, message: 'No users with newsletter enabled', sent: 0, }, { status: 200 } ) } const userIds = preferences.map((p: any) => p.user_id) // Get user emails const { data: users, error: usersError } = await supabase .from('users') .select('user_id, user_name, email') .in('user_id', userIds) if (usersError) { console.error('Error fetching users:', usersError) return NextResponse.json( { error: 'Failed to fetch users' }, { status: 500 } ) } if (!users || users.length === 0) { return NextResponse.json( { success: true, message: 'No users with newsletter enabled', sent: 0, }, { status: 200 } ) } const transporter = createTransporter() let successCount = 0 let failureCount = 0 // Send newsletter to each user for (const user of users) { try { // Build featured builds section if provided let featuredSection = '' if (featuredBuilds && Array.isArray(featuredBuilds) && featuredBuilds.length > 0) { featuredSection = `
Featured Builds
${featuredBuilds .slice(0, 3) .map( (build: any) => `
${build.name}
by ${build.createdBy}
${build.description}
View Build →
` ) .join('')}
` } const emailHtml = `

BUILDMATE

📰 Monthly Newsletter

Hello ${user.user_name},
${content}
${featuredSection}
💡 Pro Tip
Save multiple builds and compare them side-by-side to find the perfect configuration for your needs. Explore featured builds from our community for inspiration!
` await transporter.sendMail({ from: process.env.SMTP_FROM_EMAIL || 'BUILDMATE ', to: user.email, subject: title, html: emailHtml, }) successCount++ console.log(`✅ Newsletter sent to ${user.email}`) } catch (emailError) { failureCount++ console.error(`❌ Failed to send newsletter to ${user.email}:`, emailError) } } return NextResponse.json( { success: true, message: `Newsletter sent to ${successCount} users (${failureCount} failures)`, sent: successCount, failed: failureCount, }, { status: 200 } ) } catch (error) { console.error('Send newsletter error:', error) return NextResponse.json( { error: error instanceof Error ? error.message : 'Failed to send newsletter' }, { status: 500 } ) } }