import { sendEmail } from '~/server/utils/email'; import { createNocoDBClient } from '~/server/utils/nocodb'; import { calculateDaysUntilDue, calculateOverdueDays, getNextDuesDate, isPaymentOverOneYear, isDuesActuallyCurrent } from '~/utils/dues-calculations'; import { getRegistrationConfig } from '~/server/utils/admin-config'; export default defineEventHandler(async (event) => { try { const memberId = getRouterParam(event, 'id'); const { reminderType } = await readBody(event); if (!memberId) { throw createError({ statusCode: 400, statusMessage: 'Member ID is required' }); } if (!['due-soon', 'overdue'].includes(reminderType)) { throw createError({ statusCode: 400, statusMessage: 'Invalid reminder type. Must be "due-soon" or "overdue"' }); } // Get member data const nocodb = createNocoDBClient(); const member = await nocodb.findOne('nc_members', memberId); if (!member) { throw createError({ statusCode: 404, statusMessage: 'Member not found' }); } if (!member.email) { throw createError({ statusCode: 400, statusMessage: 'Member does not have an email address' }); } // Get current admin configuration for payment details const registrationConfig = getRegistrationConfig(); // Calculate dues status const memberName = member.FullName || `${member.first_name} ${member.last_name}`.trim() || 'Member'; const nextDueDate = getNextDuesDate(member); const membershipFee = `€${registrationConfig.membershipFee}`; const paymentIban = registrationConfig.iban; const accountHolder = registrationConfig.accountHolder; const portalUrl = `${process.env.NUXT_PUBLIC_DOMAIN || 'https://monacousa.org'}/dashboard`; const currentYear = new Date().getFullYear(); // Format dates const formatDate = (dateString: string | Date | null | undefined): string => { if (!dateString) return ''; try { const date = new Date(dateString); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } catch { return String(dateString); } }; let emailData; let subject; let template; if (reminderType === 'due-soon') { // Check if this member actually has dues coming due const daysUntilDue = calculateDaysUntilDue(member); if (!daysUntilDue || daysUntilDue.daysUntilDue <= 0) { throw createError({ statusCode: 400, statusMessage: 'Member does not have dues coming due soon' }); } subject = `🏎️ MonacoUSA - Annual Dues Due in ${daysUntilDue.daysUntilDue} Days`; template = 'dues-due-soon'; emailData = { memberName, memberId: member.member_id || member.Id, memberEmail: member.email, memberSince: formatDate(member.member_since), amount: membershipFee, dueDate: formatDate(daysUntilDue.nextDueDate), daysUntilDue: daysUntilDue.daysUntilDue, paymentIban, accountHolder, portalUrl, currentYear }; } else if (reminderType === 'overdue') { // Check if this member is actually overdue const isDuesCurrent = isDuesActuallyCurrent(member); if (isDuesCurrent) { throw createError({ statusCode: 400, statusMessage: 'Member does not have overdue dues' }); } const overdueDays = calculateOverdueDays(member); const originalDueDate = member.payment_due_date || nextDueDate; subject = `🚨 MonacoUSA - URGENT: Overdue Dues Notice (${overdueDays} days overdue)`; template = 'dues-overdue'; emailData = { memberName, memberId: member.member_id || member.Id, memberEmail: member.email, memberSince: formatDate(member.member_since), amount: membershipFee, originalDueDate: formatDate(originalDueDate), daysOverdue: overdueDays, paymentIban, accountHolder, portalUrl, currentYear }; } // Send the email console.log(`[Dues Reminder] Sending ${reminderType} reminder to ${member.email}`, { memberId, memberName, reminderType, emailData }); await sendEmail({ to: member.email, subject, template, data: emailData }); // Log the reminder sent (could store in database for tracking) console.log(`[Dues Reminder] Successfully sent ${reminderType} reminder to ${memberName} (${member.email})`); return { success: true, message: `${reminderType === 'due-soon' ? 'Due soon' : 'Overdue'} reminder sent successfully`, data: { memberId, memberName, memberEmail: member.email, reminderType, sentAt: new Date().toISOString() } }; } catch (error: any) { console.error('[Dues Reminder] Error sending reminder:', error); // Handle specific error cases if (error.statusCode) { throw error; } throw createError({ statusCode: 500, statusMessage: error.message || 'Failed to send dues reminder' }); } });