/**
 * Event Reminder Service
 * Handles sending automated reminder emails 24 hours before events
 */

import { supabaseAdmin } from './supabase';
import { sendTemplatedEmail } from './email';
import { sendWithPreferenceCheck } from './notification-preferences';

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

export interface EventReminderSettings {
	event_reminders_enabled: boolean;
	event_reminder_hours_before: number;
}

export interface EventReminderResult {
	sent: number;
	skipped: number;
	errors: string[];
	reminders: Array<{
		eventId: string;
		eventTitle: string;
		memberId: string;
		memberName: string;
		email: string;
		status: 'sent' | 'skipped' | 'error';
		error?: string;
	}>;
}

export interface EventNeedingReminder {
	event_id: string;
	event_title: string;
	start_datetime: string;
	end_datetime: string;
	location: string | null;
	timezone: string;
	rsvp_id: string;
	member_id: string;
	guest_count: number;
	rsvp_status: string;
	first_name: string;
	last_name: string;
	email: string;
}

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

/**
 * Get event reminder settings from the database
 */
export async function getEventReminderSettings(): Promise<EventReminderSettings> {
	const { data: settings } = await supabaseAdmin
		.from('app_settings')
		.select('setting_key, setting_value')
		.eq('category', 'events')
		.in('setting_key', ['event_reminders_enabled', 'event_reminder_hours_before']);

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

	return {
		event_reminders_enabled: config.event_reminders_enabled !== 'false',
		event_reminder_hours_before: parseInt(config.event_reminder_hours_before || '24')
	};
}

// ============================================
// QUERIES
// ============================================

/**
 * Get events with confirmed RSVPs that need reminders sent
 * Uses the events_needing_reminders view for efficient querying
 */
export async function getEventsNeedingReminders(): Promise<EventNeedingReminder[]> {
	const settings = await getEventReminderSettings();

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

	// Calculate the time window based on settings
	const hoursBeforeEvent = settings.event_reminder_hours_before;
	const now = new Date();
	const windowStart = new Date(now.getTime() + (hoursBeforeEvent - 1) * 60 * 60 * 1000);
	const windowEnd = new Date(now.getTime() + (hoursBeforeEvent + 1) * 60 * 60 * 1000);

	// Query events starting within the reminder window
	const { data: events, error } = await supabaseAdmin
		.from('events')
		.select(`
			id,
			title,
			start_datetime,
			end_datetime,
			location,
			timezone
		`)
		.eq('status', 'published')
		.gt('start_datetime', windowStart.toISOString())
		.lte('start_datetime', windowEnd.toISOString());

	if (error || !events || events.length === 0) {
		return [];
	}

	// Get RSVPs for these events
	const eventIds = events.map(e => e.id);
	const { data: rsvps, error: rsvpError } = await supabaseAdmin
		.from('event_rsvps')
		.select(`
			id,
			event_id,
			member_id,
			guest_count,
			status,
			member:members(first_name, last_name, email)
		`)
		.in('event_id', eventIds)
		.eq('status', 'confirmed');

	if (rsvpError || !rsvps) {
		return [];
	}

	// Get already sent reminders
	const { data: sentReminders } = await supabaseAdmin
		.from('event_reminder_logs')
		.select('event_id, member_id')
		.in('event_id', eventIds)
		.eq('reminder_type', '24hr');

	const sentSet = new Set(
		(sentReminders || []).map(r => `${r.event_id}-${r.member_id}`)
	);

	// Build the result array
	const result: EventNeedingReminder[] = [];

	for (const event of events) {
		const eventRsvps = rsvps.filter(r => r.event_id === event.id);

		for (const rsvp of eventRsvps) {
			const member = rsvp.member as { first_name: string; last_name: string; email: string } | null;
			if (!member?.email) continue;

			// Skip if reminder already sent
			const key = `${event.id}-${rsvp.member_id}`;
			if (sentSet.has(key)) continue;

			result.push({
				event_id: event.id,
				event_title: event.title,
				start_datetime: event.start_datetime,
				end_datetime: event.end_datetime,
				location: event.location,
				timezone: event.timezone || 'Europe/Monaco',
				rsvp_id: rsvp.id,
				member_id: rsvp.member_id,
				guest_count: rsvp.guest_count || 0,
				rsvp_status: rsvp.status,
				first_name: member.first_name,
				last_name: member.last_name,
				email: member.email
			});
		}
	}

	return result;
}

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

/**
 * Send a single event reminder email
 */
export async function sendEventReminder(
	reminder: EventNeedingReminder,
	baseUrl: string = 'https://monacousa.org'
): Promise<{ success: boolean; error?: string }> {
	// Format date and time
	const eventDate = new Date(reminder.start_datetime);
	const formattedDate = eventDate.toLocaleDateString('en-US', {
		weekday: 'long',
		month: 'long',
		day: 'numeric',
		year: 'numeric'
	});
	const formattedTime = eventDate.toLocaleTimeString('en-US', {
		hour: 'numeric',
		minute: '2-digit',
		hour12: true,
		timeZone: reminder.timezone
	});

	const variables: Record<string, string> = {
		first_name: reminder.first_name,
		event_title: reminder.event_title,
		event_date: formattedDate,
		event_time: formattedTime,
		event_location: reminder.location || 'TBD',
		guest_count: reminder.guest_count > 0 ? reminder.guest_count.toString() : '',
		portal_url: `${baseUrl}/events/${reminder.event_id}`
	};

	// Send email (respecting notification preferences)
	const result = await sendWithPreferenceCheck(reminder.member_id, 'event_reminder', () =>
		sendTemplatedEmail('event_reminder_24hr', reminder.email, variables, {
			recipientId: reminder.member_id,
			recipientName: `${reminder.first_name} ${reminder.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('event_reminder_logs').insert({
		event_id: reminder.event_id,
		rsvp_id: reminder.rsvp_id,
		member_id: reminder.member_id,
		reminder_type: '24hr'
	});

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

	return { success: true };
}

/**
 * Send all pending event reminders
 */
export async function sendEventReminders(
	baseUrl: string = 'https://monacousa.org'
): Promise<EventReminderResult> {
	const remindersNeeded = await getEventsNeedingReminders();

	const result: EventReminderResult = {
		sent: 0,
		skipped: 0,
		errors: [],
		reminders: []
	};

	for (const reminder of remindersNeeded) {
		try {
			const sendResult = await sendEventReminder(reminder, baseUrl);

			if (sendResult.success) {
				result.sent++;
				result.reminders.push({
					eventId: reminder.event_id,
					eventTitle: reminder.event_title,
					memberId: reminder.member_id,
					memberName: `${reminder.first_name} ${reminder.last_name}`,
					email: reminder.email,
					status: 'sent'
				});
			} else {
				result.errors.push(`${reminder.email}: ${sendResult.error}`);
				result.reminders.push({
					eventId: reminder.event_id,
					eventTitle: reminder.event_title,
					memberId: reminder.member_id,
					memberName: `${reminder.first_name} ${reminder.last_name}`,
					email: reminder.email,
					status: 'error',
					error: sendResult.error
				});
			}
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : 'Unknown error';
			result.errors.push(`${reminder.email}: ${errorMessage}`);
			result.reminders.push({
				eventId: reminder.event_id,
				eventTitle: reminder.event_title,
				memberId: reminder.member_id,
				memberName: `${reminder.first_name} ${reminder.last_name}`,
				email: reminder.email,
				status: 'error',
				error: errorMessage
			});
		}
	}

	return result;
}

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

/**
 * Get statistics about event reminders
 */
export async function getEventReminderStats(): Promise<{
	totalRemindersSent: number;
	remindersSentThisMonth: number;
	eventsWithReminders: number;
}> {
	const now = new Date();
	const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);

	// Get total reminders sent
	const { count: totalRemindersSent } = await supabaseAdmin
		.from('event_reminder_logs')
		.select('*', { count: 'exact', head: true });

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

	// Get unique events with reminders
	const { data: uniqueEvents } = await supabaseAdmin
		.from('event_reminder_logs')
		.select('event_id')
		.limit(10000);

	const uniqueEventIds = new Set((uniqueEvents || []).map(e => e.event_id));

	return {
		totalRemindersSent: totalRemindersSent || 0,
		remindersSentThisMonth: remindersSentThisMonth || 0,
		eventsWithReminders: uniqueEventIds.size
	};
}
