/**
 * Dues Management Service
 * Handles dues reminders, bulk operations, and analytics
 */

import { supabaseAdmin } from './supabase';
import { sendTemplatedEmail } from './email';
import { sendWithPreferenceCheck } from './notification-preferences';
import { logAudit } from './audit';
import type { MemberWithDues } from '$lib/types/database';

// ============================================
// TYPES
// ============================================

export type ReminderType = 'due_soon_30' | 'due_soon_7' | 'due_soon_1' | 'overdue' | 'grace_period' | 'inactive_notice';

// Onboarding reminder types (for new members with payment_deadline)
export type OnboardingReminderType = 'onboarding_reminder_7' | 'onboarding_reminder_1' | 'onboarding_expired';

export interface DuesSettings {
	reminder_days_before: number[];
	grace_period_days: number;
	auto_inactive_enabled: boolean;
	payment_iban: string;
	payment_account_holder: string;
	payment_bank_name: string;
}

export interface DuesReminderResult {
	sent: number;
	skipped: number;
	errors: string[];
	members: Array<{ id: string; name: string; email: string; status: 'sent' | 'skipped' | 'error'; error?: string }>;
}

export interface DuesAnalytics {
	totalMembers: number;
	current: number;
	dueSoon: number;
	overdue: number;
	neverPaid: number;
	totalCollectedThisMonth: number;
	totalCollectedThisYear: number;
	totalOutstanding: number;
	paymentsByMonth: Array<{ month: string; amount: number; count: number }>;
	remindersSentThisMonth: number;
	statusBreakdown: Array<{ status: string; count: number; percentage: number }>;
}

// ============================================
// SETTINGS
// ============================================

/**
 * Get dues-related settings from the database
 */
export async function getDuesSettings(): Promise<DuesSettings> {
	const { data: settings } = await supabaseAdmin
		.from('app_settings')
		.select('setting_key, setting_value')
		.eq('category', 'dues');

	const config: Record<string, any> = {};
	for (const s of settings || []) {
		config[s.setting_key] = s.setting_value;
	}

	return {
		reminder_days_before: Array.isArray(config.reminder_days_before)
			? config.reminder_days_before
			: [30, 7, 1],
		grace_period_days: typeof config.grace_period_days === 'number' ? config.grace_period_days : 30,
		auto_inactive_enabled:
			typeof config.auto_inactive_enabled === 'boolean' ? config.auto_inactive_enabled : true,
		payment_iban: config.payment_iban || '',
		payment_account_holder: config.payment_account_holder || '',
		payment_bank_name: config.payment_bank_name || ''
	};
}

// ============================================
// MEMBER QUERIES
// ============================================

/**
 * Get members who need a specific type of reminder
 * Excludes members who have already received this reminder for their current due date
 */
export async function getMembersNeedingReminder(reminderType: ReminderType): Promise<MemberWithDues[]> {
	const settings = await getDuesSettings();
	const today = new Date();
	today.setHours(0, 0, 0, 0);

	// Get all members with dues info
	const { data: members, error } = await supabaseAdmin
		.from('members_with_dues')
		.select('*')
		.not('email', 'is', null);

	if (error || !members) {
		console.error('Error fetching members:', error);
		return [];
	}

	// Filter based on reminder type
	let filteredMembers: MemberWithDues[] = [];

	if (reminderType.startsWith('due_soon_')) {
		const daysMatch = reminderType.match(/due_soon_(\d+)/);
		if (!daysMatch) return [];
		const daysBefore = parseInt(daysMatch[1]);

		filteredMembers = members.filter((m) => {
			if (!m.current_due_date || m.dues_status === 'never_paid') return false;
			const dueDate = new Date(m.current_due_date);
			const daysUntil = Math.ceil((dueDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
			// Member is due within the specified window (e.g., 30 days means dues_until <= 30)
			return daysUntil > 0 && daysUntil <= daysBefore;
		});
	} else if (reminderType === 'overdue') {
		filteredMembers = members.filter((m) => {
			if (!m.current_due_date) return false;
			const daysOverdue = m.days_overdue || 0;
			// Overdue but still within grace period
			return m.dues_status === 'overdue' && daysOverdue <= settings.grace_period_days;
		});
	} else if (reminderType === 'grace_period') {
		filteredMembers = members.filter((m) => {
			if (!m.current_due_date) return false;
			const daysOverdue = m.days_overdue || 0;
			// In final week of grace period
			const graceDaysRemaining = settings.grace_period_days - daysOverdue;
			return m.dues_status === 'overdue' && graceDaysRemaining > 0 && graceDaysRemaining <= 7;
		});
	}

	// Exclude members who already received this reminder for their current due period
	if (filteredMembers.length > 0) {
		const memberIds = filteredMembers.map((m) => m.id);

		// Get reminders already sent
		const { data: existingReminders } = await supabaseAdmin
			.from('dues_reminder_logs')
			.select('member_id, due_date')
			.eq('reminder_type', reminderType)
			.in('member_id', memberIds);

		if (existingReminders && existingReminders.length > 0) {
			const sentSet = new Set(
				existingReminders.map((r) => `${r.member_id}-${r.due_date}`)
			);

			filteredMembers = filteredMembers.filter((m) => {
				const key = `${m.id}-${m.current_due_date}`;
				return !sentSet.has(key);
			});
		}
	}

	return filteredMembers;
}

/**
 * Get overdue members who have exceeded the grace period and should be marked inactive
 */
export async function getMembersForInactivation(): Promise<MemberWithDues[]> {
	const settings = await getDuesSettings();

	if (!settings.auto_inactive_enabled) {
		return [];
	}

	const { data: members } = await supabaseAdmin
		.from('members_with_dues')
		.select('*')
		.eq('dues_status', 'overdue')
		.not('status_name', 'eq', 'inactive');

	if (!members) return [];

	// Filter to those past grace period
	return members.filter((m) => {
		const daysOverdue = m.days_overdue || 0;
		return daysOverdue > settings.grace_period_days;
	});
}

// ============================================
// REMINDER SENDING
// ============================================

/**
 * Send a dues reminder to a specific member
 */
export async function sendDuesReminder(
	member: MemberWithDues,
	reminderType: ReminderType,
	baseUrl: string = 'https://monacousa.org'
): Promise<{ success: boolean; error?: string; emailLogId?: string }> {
	const settings = await getDuesSettings();

	// Determine template key based on reminder type
	const templateKey =
		reminderType === 'overdue'
			? 'dues_overdue'
			: reminderType === 'grace_period'
				? 'dues_grace_warning'
				: reminderType === 'inactive_notice'
					? 'dues_inactive_notice'
					: `dues_reminder_${reminderType.replace('due_soon_', '')}`;

	// Calculate variables
	const dueDate = member.current_due_date
		? new Date(member.current_due_date).toLocaleDateString('en-US', {
				month: 'long',
				day: 'numeric',
				year: 'numeric'
			})
		: 'N/A';

	const daysOverdue = member.days_overdue || 0;
	const graceDaysRemaining = Math.max(0, settings.grace_period_days - daysOverdue);
	const graceEndDate = member.current_due_date
		? new Date(
				new Date(member.current_due_date).getTime() +
					settings.grace_period_days * 24 * 60 * 60 * 1000
			).toLocaleDateString('en-US', {
				month: 'long',
				day: 'numeric',
				year: 'numeric'
			})
		: 'N/A';

	const variables: Record<string, string> = {
		first_name: member.first_name,
		last_name: member.last_name,
		member_id: member.member_id,
		due_date: dueDate,
		amount: `€${(member.annual_dues || 50).toFixed(2)}`,
		days_overdue: daysOverdue.toString(),
		grace_days_remaining: graceDaysRemaining.toString(),
		grace_end_date: graceEndDate,
		account_holder: settings.payment_account_holder,
		bank_name: settings.payment_bank_name,
		iban: settings.payment_iban,
		portal_url: `${baseUrl}/payments`
	};

	// Send email (respecting notification preferences)
	const result = await sendWithPreferenceCheck(member.id, 'dues_reminder', () =>
		sendTemplatedEmail(templateKey, member.email, variables, {
			recipientId: member.id,
			recipientName: `${member.first_name} ${member.last_name}`,
			baseUrl
		})
	);

	if (!result.success) {
		return { success: false, error: 'error' in result ? result.error : undefined };
	}

	// Log the reminder
	const { error: logError } = await supabaseAdmin.from('dues_reminder_logs').insert({
		member_id: member.id,
		reminder_type: reminderType,
		due_date: member.current_due_date || new Date().toISOString().split('T')[0]
	});

	if (logError) {
		console.error('Error logging reminder:', logError);
	}

	return { success: true };
}

/**
 * Send bulk reminders of a specific type
 */
export async function sendBulkReminders(
	reminderType: ReminderType,
	baseUrl: string = 'https://monacousa.org'
): Promise<DuesReminderResult> {
	const members = await getMembersNeedingReminder(reminderType);

	const result: DuesReminderResult = {
		sent: 0,
		skipped: 0,
		errors: [],
		members: []
	};

	for (const member of members) {
		try {
			const sendResult = await sendDuesReminder(member, reminderType, baseUrl);

			if (sendResult.success) {
				result.sent++;
				result.members.push({
					id: member.id,
					name: `${member.first_name} ${member.last_name}`,
					email: member.email,
					status: 'sent'
				});
			} else {
				result.errors.push(`${member.email}: ${sendResult.error}`);
				result.members.push({
					id: member.id,
					name: `${member.first_name} ${member.last_name}`,
					email: member.email,
					status: 'error',
					error: sendResult.error
				});
			}
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : 'Unknown error';
			result.errors.push(`${member.email}: ${errorMessage}`);
			result.members.push({
				id: member.id,
				name: `${member.first_name} ${member.last_name}`,
				email: member.email,
				status: 'error',
				error: errorMessage
			});
		}
	}

	if (result.sent > 0) {
		logAudit({
			action: 'email.send',
			resourceType: 'dues_reminder',
			details: {
				reminder_type: reminderType,
				total_sent: result.sent,
				total_errors: result.errors.length,
				bulk_operation: true
			}
		});
	}

	return result;
}

// ============================================
// GRACE PERIOD & INACTIVATION
// ============================================

/**
 * Process members who have exceeded grace period and mark them inactive
 */
export async function processGracePeriodExpirations(
	baseUrl: string = 'https://monacousa.org'
): Promise<{ processed: number; members: Array<{ id: string; name: string; email: string }> }> {
	const settings = await getDuesSettings();

	if (!settings.auto_inactive_enabled) {
		return { processed: 0, members: [] };
	}

	const members = await getMembersForInactivation();
	const processed: Array<{ id: string; name: string; email: string }> = [];

	// Get inactive status ID
	const { data: inactiveStatus } = await supabaseAdmin
		.from('membership_statuses')
		.select('id')
		.eq('name', 'inactive')
		.single();

	if (!inactiveStatus) {
		console.error('Inactive status not found');
		return { processed: 0, members: [] };
	}

	for (const member of members) {
		// Update member status to inactive
		const { error: updateError } = await supabaseAdmin
			.from('members')
			.update({ membership_status_id: inactiveStatus.id })
			.eq('id', member.id);

		if (updateError) {
			console.error(`Error updating member ${member.id}:`, updateError);
			continue;
		}

		// Send inactive notice
		await sendDuesReminder(member, 'inactive_notice', baseUrl);

		// Log the reminder
		await supabaseAdmin.from('dues_reminder_logs').insert({
			member_id: member.id,
			reminder_type: 'inactive_notice',
			due_date: member.current_due_date || new Date().toISOString().split('T')[0]
		});

		processed.push({
			id: member.id,
			name: `${member.first_name} ${member.last_name}`,
			email: member.email
		});
	}

	if (processed.length > 0) {
		logAudit({
			action: 'member.status_change',
			resourceType: 'member',
			details: {
				operation: 'grace_period_expiration',
				members_inactivated: processed.length,
				member_ids: processed.map(m => m.id)
			}
		});
	}

	return { processed: processed.length, members: processed };
}

// ============================================
// ANALYTICS
// ============================================

/**
 * Get comprehensive dues analytics
 */
export async function getDuesAnalytics(): Promise<DuesAnalytics> {
	const now = new Date();
	const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
	const startOfYear = new Date(now.getFullYear(), 0, 1);

	// Get members with dues
	const { data: members } = await supabaseAdmin.from('members_with_dues').select('*');

	const allMembers = members || [];
	const totalMembers = allMembers.length;
	const current = allMembers.filter((m) => m.dues_status === 'current').length;
	const dueSoon = allMembers.filter((m) => m.dues_status === 'due_soon').length;
	const overdue = allMembers.filter((m) => m.dues_status === 'overdue').length;
	const neverPaid = allMembers.filter((m) => m.dues_status === 'never_paid').length;

	// Calculate total outstanding (overdue + due_soon + never_paid)
	const totalOutstanding = allMembers
		.filter((m) => m.dues_status !== 'current')
		.reduce((sum, m) => sum + (m.annual_dues || 0), 0);

	// Get payments this month
	const { data: monthPayments } = await supabaseAdmin
		.from('dues_payments')
		.select('amount')
		.gte('payment_date', startOfMonth.toISOString().split('T')[0]);

	const totalCollectedThisMonth = (monthPayments || []).reduce((sum, p) => sum + p.amount, 0);

	// Get payments this year
	const { data: yearPayments } = await supabaseAdmin
		.from('dues_payments')
		.select('amount')
		.gte('payment_date', startOfYear.toISOString().split('T')[0]);

	const totalCollectedThisYear = (yearPayments || []).reduce((sum, p) => sum + p.amount, 0);

	// Get payments by month (last 12 months)
	const twelveMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 11, 1);
	const { data: allPayments } = await supabaseAdmin
		.from('dues_payments')
		.select('amount, payment_date')
		.gte('payment_date', twelveMonthsAgo.toISOString().split('T')[0])
		.order('payment_date', { ascending: true });

	const paymentsByMonth: Array<{ month: string; amount: number; count: number }> = [];
	const monthMap = new Map<string, { amount: number; count: number }>();

	for (const payment of allPayments || []) {
		const date = new Date(payment.payment_date);
		const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;

		const existing = monthMap.get(monthKey) || { amount: 0, count: 0 };
		existing.amount += payment.amount;
		existing.count += 1;
		monthMap.set(monthKey, existing);
	}

	// Fill in missing months
	for (let i = 0; i < 12; i++) {
		const date = new Date(now.getFullYear(), now.getMonth() - 11 + i, 1);
		const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
		const data = monthMap.get(monthKey) || { amount: 0, count: 0 };
		paymentsByMonth.push({
			month: date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' }),
			amount: data.amount,
			count: data.count
		});
	}

	// Get reminders sent this month
	const { count: remindersSentThisMonth } = await supabaseAdmin
		.from('dues_reminder_logs')
		.select('*', { count: 'exact', head: true })
		.gte('sent_at', startOfMonth.toISOString());

	// Status breakdown with percentages
	const statusBreakdown = [
		{ status: 'current', count: current, percentage: totalMembers > 0 ? (current / totalMembers) * 100 : 0 },
		{ status: 'due_soon', count: dueSoon, percentage: totalMembers > 0 ? (dueSoon / totalMembers) * 100 : 0 },
		{ status: 'overdue', count: overdue, percentage: totalMembers > 0 ? (overdue / totalMembers) * 100 : 0 },
		{ status: 'never_paid', count: neverPaid, percentage: totalMembers > 0 ? (neverPaid / totalMembers) * 100 : 0 }
	];

	return {
		totalMembers,
		current,
		dueSoon,
		overdue,
		neverPaid,
		totalCollectedThisMonth,
		totalCollectedThisYear,
		totalOutstanding,
		paymentsByMonth,
		remindersSentThisMonth: remindersSentThisMonth || 0,
		statusBreakdown
	};
}

/**
 * Get detailed dues report data for CSV export
 */
export async function getDuesReportData(): Promise<{
	members: Array<{
		member_id: string;
		name: string;
		email: string;
		membership_type: string;
		status: string;
		dues_status: string;
		annual_dues: number;
		last_payment_date: string | null;
		current_due_date: string | null;
		days_overdue: number | null;
	}>;
	payments: Array<{
		member_id: string;
		member_name: string;
		amount: number;
		payment_date: string;
		payment_method: string;
		reference: string | null;
		recorded_by: string | null;
	}>;
}> {
	// Get members with dues
	const { data: members } = await supabaseAdmin.from('members_with_dues').select('*');

	const memberReport = (members || []).map((m) => ({
		member_id: m.member_id,
		name: `${m.first_name} ${m.last_name}`,
		email: m.email,
		membership_type: m.membership_type_name || 'Regular',
		status: m.status_display_name || 'Unknown',
		dues_status: m.dues_status,
		annual_dues: m.annual_dues || 0,
		last_payment_date: m.last_payment_date,
		current_due_date: m.current_due_date,
		days_overdue: m.days_overdue
	}));

	// Get all payments with member info
	const { data: payments } = await supabaseAdmin
		.from('dues_payments')
		.select(
			`
			*,
			member:members(member_id, first_name, last_name),
			recorder:members!dues_payments_recorded_by_fkey(first_name, last_name)
		`
		)
		.order('payment_date', { ascending: false });

	const paymentReport = (payments || []).map((p: any) => ({
		member_id: p.member?.member_id || 'Unknown',
		member_name: p.member ? `${p.member.first_name} ${p.member.last_name}` : 'Unknown',
		amount: p.amount,
		payment_date: p.payment_date,
		payment_method: p.payment_method,
		reference: p.reference,
		recorded_by: p.recorder ? `${p.recorder.first_name} ${p.recorder.last_name}` : null
	}));

	return {
		members: memberReport,
		payments: paymentReport
	};
}

/**
 * Get reminder effectiveness stats
 */
export async function getReminderEffectiveness(): Promise<{
	totalRemindersSent: number;
	paidWithin7Days: number;
	paidWithin30Days: number;
	effectivenessRate: number;
}> {
	// Get all reminder logs with payment data
	const { data: reminders } = await supabaseAdmin
		.from('dues_reminder_logs')
		.select('member_id, sent_at, due_date');

	if (!reminders || reminders.length === 0) {
		return {
			totalRemindersSent: 0,
			paidWithin7Days: 0,
			paidWithin30Days: 0,
			effectivenessRate: 0
		};
	}

	// Collect unique member IDs and earliest sent_at per member
	const memberIds = [...new Set(reminders.map((r) => r.member_id))];

	// Find the earliest sent_at across all reminders to bound the payment query
	const earliestSentAt = reminders.reduce((earliest, r) => {
		const d = new Date(r.sent_at);
		return d < earliest ? d : earliest;
	}, new Date(reminders[0].sent_at));

	// Find the latest possible payment date (latest sent_at + 30 days)
	const latestSentAt = reminders.reduce((latest, r) => {
		const d = new Date(r.sent_at);
		return d > latest ? d : latest;
	}, new Date(reminders[0].sent_at));
	const latestPaymentDate = new Date(latestSentAt.getTime() + 30 * 24 * 60 * 60 * 1000);

	// Fetch all relevant payments in a single batch query
	const { data: allPayments } = await supabaseAdmin
		.from('dues_payments')
		.select('member_id, payment_date')
		.in('member_id', memberIds)
		.gte('payment_date', earliestSentAt.toISOString().split('T')[0])
		.lte('payment_date', latestPaymentDate.toISOString().split('T')[0]);

	// Index payments by member_id for fast lookup
	const paymentsByMember = new Map<string, { payment_date: string }[]>();
	if (allPayments) {
		for (const p of allPayments) {
			const existing = paymentsByMember.get(p.member_id) || [];
			existing.push(p);
			paymentsByMember.set(p.member_id, existing);
		}
	}

	let paidWithin7Days = 0;
	let paidWithin30Days = 0;

	for (const reminder of reminders) {
		const sentDate = new Date(reminder.sent_at);
		const sevenDaysLater = new Date(sentDate.getTime() + 7 * 24 * 60 * 60 * 1000);
		const thirtyDaysLater = new Date(sentDate.getTime() + 30 * 24 * 60 * 60 * 1000);

		const memberPayments = paymentsByMember.get(reminder.member_id) || [];

		// Find a payment within the 30-day window after the reminder
		const matchingPayment = memberPayments.find((p) => {
			const paymentDate = new Date(p.payment_date);
			return paymentDate >= sentDate && paymentDate <= thirtyDaysLater;
		});

		if (matchingPayment) {
			const paymentDate = new Date(matchingPayment.payment_date);
			if (paymentDate <= sevenDaysLater) {
				paidWithin7Days++;
			}
			paidWithin30Days++;
		}
	}

	return {
		totalRemindersSent: reminders.length,
		paidWithin7Days,
		paidWithin30Days,
		effectivenessRate: reminders.length > 0 ? (paidWithin30Days / reminders.length) * 100 : 0
	};
}

// ============================================
// ONBOARDING REMINDERS
// ============================================

interface OnboardingMember {
	id: string;
	first_name: string;
	last_name: string;
	email: string;
	member_id: string;
	payment_deadline: string;
}

/**
 * Get new members who need onboarding payment reminders
 * These are members with a payment_deadline set from onboarding
 */
export async function getMembersNeedingOnboardingReminder(
	reminderType: OnboardingReminderType
): Promise<OnboardingMember[]> {
	const today = new Date();
	today.setHours(0, 0, 0, 0);

	// Get pending status ID
	const { data: pendingStatus } = await supabaseAdmin
		.from('membership_statuses')
		.select('id')
		.eq('name', 'pending')
		.single();

	if (!pendingStatus) {
		console.error('Pending status not found');
		return [];
	}

	// Get members with payment_deadline set (from onboarding)
	const { data: members, error } = await supabaseAdmin
		.from('members')
		.select('id, first_name, last_name, email, member_id, payment_deadline')
		.eq('membership_status_id', pendingStatus.id)
		.not('payment_deadline', 'is', null)
		.not('email', 'is', null);

	if (error || !members) {
		console.error('Error fetching onboarding members:', error);
		return [];
	}

	// Filter based on reminder type
	let filteredMembers: OnboardingMember[] = [];

	if (reminderType === 'onboarding_reminder_7') {
		// 7 days or less until deadline
		filteredMembers = members.filter((m) => {
			if (!m.payment_deadline) return false;
			const deadline = new Date(m.payment_deadline);
			const daysUntil = Math.ceil((deadline.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
			return daysUntil > 0 && daysUntil <= 7;
		}) as OnboardingMember[];
	} else if (reminderType === 'onboarding_reminder_1') {
		// 1 day or less until deadline (final reminder)
		filteredMembers = members.filter((m) => {
			if (!m.payment_deadline) return false;
			const deadline = new Date(m.payment_deadline);
			const daysUntil = Math.ceil((deadline.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
			return daysUntil === 1;
		}) as OnboardingMember[];
	} else if (reminderType === 'onboarding_expired') {
		// Deadline has passed
		filteredMembers = members.filter((m) => {
			if (!m.payment_deadline) return false;
			const deadline = new Date(m.payment_deadline);
			return deadline < today;
		}) as OnboardingMember[];
	}

	// Exclude members who already received this reminder
	if (filteredMembers.length > 0) {
		const memberIds = filteredMembers.map((m) => m.id);

		const { data: existingReminders } = await supabaseAdmin
			.from('dues_reminder_logs')
			.select('member_id')
			.eq('reminder_type', reminderType)
			.in('member_id', memberIds);

		if (existingReminders && existingReminders.length > 0) {
			const sentSet = new Set(existingReminders.map((r) => r.member_id));
			filteredMembers = filteredMembers.filter((m) => !sentSet.has(m.id));
		}
	}

	return filteredMembers;
}

/**
 * Send an onboarding reminder to a specific member
 */
export async function sendOnboardingReminder(
	member: OnboardingMember,
	reminderType: OnboardingReminderType,
	baseUrl: string = 'https://monacousa.org'
): Promise<{ success: boolean; error?: string }> {
	const settings = await getDuesSettings();

	// Calculate days until deadline
	const deadline = new Date(member.payment_deadline);
	const today = new Date();
	today.setHours(0, 0, 0, 0);
	const daysLeft = Math.ceil((deadline.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));

	// Get default membership dues amount
	const { data: defaultType } = await supabaseAdmin
		.from('membership_types')
		.select('annual_dues')
		.eq('is_default', true)
		.single();

	const variables: Record<string, string> = {
		first_name: member.first_name,
		last_name: member.last_name,
		member_id: member.member_id || 'N/A',
		payment_deadline: deadline.toLocaleDateString('en-US', {
			weekday: 'long',
			year: 'numeric',
			month: 'long',
			day: 'numeric'
		}),
		days_remaining: Math.max(0, daysLeft).toString(),
		amount: `€${defaultType?.annual_dues || 150}`,
		account_holder: settings.payment_account_holder || 'Monaco USA',
		bank_name: settings.payment_bank_name || 'Credit Foncier de Monaco',
		iban: settings.payment_iban || 'Contact for details',
		portal_url: `${baseUrl}/payments`
	};

	// Send email (respecting notification preferences)
	const result = await sendWithPreferenceCheck(member.id, 'dues_reminder', () =>
		sendTemplatedEmail(reminderType, member.email, variables, {
			recipientId: member.id,
			recipientName: `${member.first_name} ${member.last_name}`,
			baseUrl
		})
	);

	if (!result.success) {
		return { success: false, error: 'error' in result ? result.error : undefined };
	}

	// Log the reminder
	const { error: logError } = await supabaseAdmin.from('dues_reminder_logs').insert({
		member_id: member.id,
		reminder_type: reminderType,
		due_date: member.payment_deadline
	});

	if (logError) {
		console.error('Error logging onboarding reminder:', logError);
	}

	return { success: true };
}

/**
 * Send bulk onboarding reminders of a specific type
 */
export async function sendOnboardingReminders(
	reminderType: OnboardingReminderType,
	baseUrl: string = 'https://monacousa.org'
): Promise<DuesReminderResult> {
	const members = await getMembersNeedingOnboardingReminder(reminderType);

	const result: DuesReminderResult = {
		sent: 0,
		skipped: 0,
		errors: [],
		members: []
	};

	for (const member of members) {
		try {
			const sendResult = await sendOnboardingReminder(member, reminderType, baseUrl);

			if (sendResult.success) {
				result.sent++;
				result.members.push({
					id: member.id,
					name: `${member.first_name} ${member.last_name}`,
					email: member.email,
					status: 'sent'
				});
			} else {
				result.errors.push(`${member.email}: ${sendResult.error}`);
				result.members.push({
					id: member.id,
					name: `${member.first_name} ${member.last_name}`,
					email: member.email,
					status: 'error',
					error: sendResult.error
				});
			}
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : 'Unknown error';
			result.errors.push(`${member.email}: ${errorMessage}`);
			result.members.push({
				id: member.id,
				name: `${member.first_name} ${member.last_name}`,
				email: member.email,
				status: 'error',
				error: errorMessage
			});
		}
	}

	return result;
}

/**
 * Process expired onboarding payment deadlines and mark members as inactive
 */
export async function processOnboardingExpirations(
	baseUrl: string = 'https://monacousa.org'
): Promise<{ processed: number; members: Array<{ id: string; name: string; email: string }> }> {
	const members = await getMembersNeedingOnboardingReminder('onboarding_expired');
	const processed: Array<{ id: string; name: string; email: string }> = [];

	// Get inactive status ID
	const { data: inactiveStatus } = await supabaseAdmin
		.from('membership_statuses')
		.select('id')
		.eq('name', 'inactive')
		.single();

	if (!inactiveStatus) {
		console.error('Inactive status not found');
		return { processed: 0, members: [] };
	}

	for (const member of members) {
		// Update member status to inactive
		const { error: updateError } = await supabaseAdmin
			.from('members')
			.update({ membership_status_id: inactiveStatus.id })
			.eq('id', member.id);

		if (updateError) {
			console.error(`Error updating member ${member.id}:`, updateError);
			continue;
		}

		// Send expired notice
		await sendOnboardingReminder(member, 'onboarding_expired', baseUrl);

		processed.push({
			id: member.id,
			name: `${member.first_name} ${member.last_name}`,
			email: member.email
		});
	}

	return { processed: processed.length, members: processed };
}
