import { supabaseAdmin } from './supabase';

/**
 * Notification types that map to user_notification_preferences columns.
 * The column names follow the pattern: email_{notification_type}
 */
export type NotificationType =
	| 'event_rsvp_confirmation'
	| 'event_reminder'
	| 'event_updates'
	| 'waitlist_promotion'
	| 'dues_reminder'
	| 'payment_confirmation'
	| 'membership_updates'
	| 'announcements'
	| 'newsletter';

/** Map from notification type to the corresponding column in user_notification_preferences */
const COLUMN_MAP: Record<NotificationType, string> = {
	event_rsvp_confirmation: 'email_event_rsvp_confirmation',
	event_reminder: 'email_event_reminder',
	event_updates: 'email_event_updates',
	waitlist_promotion: 'email_waitlist_promotion',
	dues_reminder: 'email_dues_reminder',
	payment_confirmation: 'email_payment_confirmation',
	membership_updates: 'email_membership_updates',
	announcements: 'email_announcements',
	newsletter: 'email_newsletter'
};

/** Critical notification types that are ALWAYS sent regardless of preferences */
const CRITICAL_TYPES = new Set([
	'password_reset',
	'account_verification',
	'member_approved',
	'member_rejected',
	'welcome'
]);

/**
 * Check if a member has email notifications enabled for a given type.
 * Returns true if enabled or if no preference record exists (opt-out model).
 * Always returns true for critical notification types.
 */
export async function hasEmailNotificationEnabled(
	memberId: string,
	notificationType: string
): Promise<boolean> {
	// Critical notifications always go through
	if (CRITICAL_TYPES.has(notificationType)) {
		return true;
	}

	// Look up the column name for this notification type
	const column = COLUMN_MAP[notificationType as NotificationType];
	if (!column) {
		// Unknown type - default to sending
		return true;
	}

	try {
		const { data } = await supabaseAdmin
			.from('user_notification_preferences')
			.select(column)
			.eq('member_id', memberId)
			.single();

		// If no preference exists, default to enabled (opt-out model)
		if (!data) return true;

		return (data as Record<string, boolean>)[column] !== false;
	} catch {
		// On error, default to sending (fail open for notifications)
		return true;
	}
}

/**
 * Send email only if user's notification preferences allow it.
 * Wraps any email sending function with a preference check.
 *
 * @param memberId - The member to check preferences for
 * @param notificationType - The type of notification
 * @param sendFn - The function to call to send the email
 * @returns The result of sendFn, or { success: true, skipped: true } if preferences disabled
 */
export async function sendWithPreferenceCheck<T extends { success: boolean }>(
	memberId: string,
	notificationType: string,
	sendFn: () => Promise<T>
): Promise<T | { success: true; skipped: true }> {
	const enabled = await hasEmailNotificationEnabled(memberId, notificationType);

	if (!enabled) {
		return { success: true, skipped: true };
	}

	return sendFn();
}
