import { NextRequest, NextResponse } from "next/server"; import * as admin from "firebase-admin"; import { Resend } from "resend"; import adminCred from "@/config/firebase-admin"; if (!admin.apps.length) { admin.initializeApp({ credential: admin.credential.cert(adminCred as admin.ServiceAccount), }); } const db = admin.firestore(); const resend = new Resend(process.env.RESEND_API_KEY); const EVENTS: Record = { registration: { title: "Engagement Ceremony", date: "23rd November 2025", venue: "Venue City", isoDate: "2025-11-23", details: "Join us for the Engagement Ceremony of the couple", startTime: "20251123T043000Z", endTime: "20251123T083000Z", location: "Venue Name, City" }, wedding: { title: "Wedding Ceremony", date: "23rd January 2026", venue: "Venue City", isoDate: "2026-01-23", details: "The Wedding Ceremony", startTime: "20260123T123000Z", endTime: "20260123T163000Z", location: "Venue Name, City" }, reception: { title: "Reception Celebration", date: "25th January 2026", venue: "Venue City", isoDate: "2026-01-25", details: "Reception Party for the couple", startTime: "20260125T123000Z", endTime: "20260125T163000Z", location: "Venue Name, City" }, }; const getCalendarLink = (event: any) => { return `https://calendar.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(event.title)}&dates=${event.startTime}/${event.endTime}&details=${encodeURIComponent(event.details)}&location=${encodeURIComponent(event.location)}`; }; const getDaysToGo = (isoDate: string) => { const eventDate = new Date(isoDate); // Get current time in IST const nowIST = new Date(new Date().toLocaleString("en-US", { timeZone: "Asia/Kolkata" })); eventDate.setHours(0, 0, 0, 0); nowIST.setHours(0, 0, 0, 0); const diffTime = eventDate.getTime() - nowIST.getTime(); const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); if (diffDays === 0) return "TODAY! 🎉"; if (diffDays === 1) return "TOMORROW! ⏳"; if (diffDays < 0) return "Completed ✔️"; return `${diffDays} days to go`; }; const emailTemplate = (guestName: string, invitedFor: string[] = []) => { const eventDetailsHtml = invitedFor .map((eventKey) => { const event = EVENTS[eventKey.toLowerCase()]; if (!event) return ""; const daysMessage = getDaysToGo(event.isoDate); const calendarLink = getCalendarLink(event); return `
${event.title} ${daysMessage}
📅 ${event.date}
📍 ${event.venue}
📅 Add to Calendar

`; }) .join(""); return `
Groom & Bride

Dear ${guestName},

We are counting down the days and are so excited to celebrate our union with you! This is a gentle reminder that our big day is just around the corner.

${eventDetailsHtml ? `
${eventDetailsHtml}
` : ''}

Please visit our wedding website for the full schedule, maps, and travel guide.

View Wedding Details

With Love,
Groom & Bride

`; }; export async function GET(request: NextRequest) { const authHeader = request.headers.get('Authorization'); if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) { return new Response('Unauthorized', { status: 401 }); } try { const snapshot = await db.collection("email-reminders").get(); if (snapshot.empty) { return NextResponse.json({ message: "No email reminders found." }); } // Deduplicate by email const uniqueRecipients = new Map(); snapshot.docs.forEach(doc => { const data = doc.data(); if (data.email) { uniqueRecipients.set(data.email, data); } }); const results = []; const recipients = Array.from(uniqueRecipients.values()); // Get current time in IST const nowIST = new Date(new Date().toLocaleString("en-US", { timeZone: "Asia/Kolkata" })); const isFutureOrToday = (isoDateStr: string) => { const eventDate = new Date(isoDateStr); // Set event date to end of day in IST eventDate.setHours(23, 59, 59, 999); return eventDate >= nowIST; }; for (const recipient of recipients) { const { email, guestName, invitedFor } = recipient; const upcomingEvents = (invitedFor || []).filter((eventKey: string) => { const evt = EVENTS[eventKey.toLowerCase()]; return evt && isFutureOrToday(evt.isoDate); }); if (upcomingEvents.length === 0) { results.push({ email, status: 'skipped', reason: 'No upcoming events' }); continue; } try { const { data: emailData, error } = await resend.emails.send({ from: 'Groom & Bride ', to: [email], subject: "Reminder: Wedding Celebration! 🎉", html: emailTemplate(guestName || "Guest", upcomingEvents), }); if (error) { console.error(`Failed to send to ${email}:`, error); results.push({ email, status: 'failed', error }); } else { results.push({ email, status: 'sent', id: emailData?.id }); } } catch (err) { console.error(`Exception sending to ${email}:`, err); results.push({ email, status: 'failed', error: err }); } } const sentCount = results.filter(r => r?.status === 'sent').length; const failedCount = results.length - sentCount; // Send Report to Admin const reportHtml = `

Email Reminder Report

Total Unique Recipients: ${results.length}

Successfully Sent: ${sentCount}

Failed: ${failedCount}


Details:

    ${results.map(r => `
  • ${r.email}: ${r.status} ${r.error ? `(${JSON.stringify(r.error)})` : ''}
  • `).join('')}
`; try { await resend.emails.send({ from: 'Wedding Bot ', to: [process.env.ADMIN_EMAIL || 'admin@example.com'], subject: `Wedding Reminder Report: ${sentCount}/${results.length} Sent`, html: reportHtml, }); } catch (reportError) { console.error("Failed to send admin report:", reportError); } return NextResponse.json({ success: true, total: results.length, sent: sentCount, failed: failedCount, results }); } catch (error) { console.error("Error processing email reminders:", error); return NextResponse.json( { error: "Internal Server Error" }, { status: 500 } ); } }