import { fail } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
import { supabaseAdmin } from '$lib/server/supabase';
import { sendEmail, sendTemplatedEmail, getSmtpConfig, wrapInMonacoTemplate } from '$lib/server/email';

export const load: PageServerLoad = async ({ locals }) => {
	const { member } = await locals.safeGetSession();

	if (!member || member.role !== 'admin') {
		return {
			templates: [],
			recentLogs: [],
			smtpConfigured: false
		};
	}

	// Check if SMTP is configured
	const smtpConfig = await getSmtpConfig();
	const smtpConfigured = !!smtpConfig;

	// Fetch all email templates
	const { data: templates } = await supabaseAdmin
		.from('email_templates')
		.select('*')
		.order('category', { ascending: true })
		.order('name', { ascending: true });

	// Fetch recent email logs
	const { data: recentLogs } = await supabaseAdmin
		.from('email_logs')
		.select(`
			*,
			sender:members!email_logs_sent_by_fkey(first_name, last_name)
		`)
		.order('created_at', { ascending: false })
		.limit(20);

	// Group templates by category
	const templatesByCategory: Record<string, typeof templates> = {};
	for (const template of templates || []) {
		const category = template.category || 'other';
		if (!templatesByCategory[category]) {
			templatesByCategory[category] = [];
		}
		templatesByCategory[category].push(template);
	}

	return {
		templates: templates || [],
		templatesByCategory,
		recentLogs: recentLogs || [],
		smtpConfigured,
		adminEmail: member.email
	};
};

export const actions: Actions = {
	/**
	 * Send a test email using a template
	 */
	sendTestTemplate: async ({ request, locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || member.role !== 'admin') {
			return fail(403, { error: 'Only admins can send test emails' });
		}

		const formData = await request.formData();
		const templateKey = formData.get('template_key') as string;
		const recipientEmail = formData.get('recipient_email') as string;

		if (!templateKey || !recipientEmail) {
			return fail(400, { error: 'Template and recipient email are required' });
		}

		// Validate email format
		const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
		if (!emailRegex.test(recipientEmail)) {
			return fail(400, { error: 'Please enter a valid email address' });
		}

		// Build test variables based on template type
		const testVariables = getTestVariables(templateKey, member, url.origin);

		const result = await sendTemplatedEmail(templateKey, recipientEmail, testVariables, {
			recipientId: member.id,
			recipientName: `${member.first_name} ${member.last_name}`,
			sentBy: member.id,
			baseUrl: url.origin
		});

		if (!result.success) {
			return fail(500, { error: result.error || 'Failed to send test email' });
		}

		return { success: `Test email sent successfully to ${recipientEmail}!` };
	},

	/**
	 * Send a custom test email
	 */
	sendCustomEmail: async ({ request, locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || member.role !== 'admin') {
			return fail(403, { error: 'Only admins can send test emails' });
		}

		const formData = await request.formData();
		const recipientEmail = formData.get('recipient_email') as string;
		const subject = formData.get('subject') as string;
		const messageContent = formData.get('message') as string;

		if (!recipientEmail || !subject || !messageContent) {
			return fail(400, { error: 'Recipient, subject, and message are required' });
		}

		// Validate email format
		const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
		if (!emailRegex.test(recipientEmail)) {
			return fail(400, { error: 'Please enter a valid email address' });
		}

		// Wrap the message in the Monaco template
		const logoUrl = `${url.origin}/MONACOUSA-Flags_376x376.png`;
		const html = wrapInMonacoTemplate({
			title: subject,
			content: `<p style="margin: 0 0 16px 0; color: #334155; line-height: 1.6;">${messageContent.replace(/\n/g, '<br>')}</p>`,
			logoUrl
		});

		const result = await sendEmail({
			to: recipientEmail,
			subject,
			html,
			emailType: 'test_custom',
			sentBy: member.id
		});

		if (!result.success) {
			return fail(500, { error: result.error || 'Failed to send email' });
		}

		return { success: `Custom email sent successfully to ${recipientEmail}!` };
	},

	/**
	 * Test all notification types to a single recipient
	 */
	sendAllTests: async ({ request, locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || member.role !== 'admin') {
			return fail(403, { error: 'Only admins can send test emails' });
		}

		const formData = await request.formData();
		const recipientEmail = formData.get('recipient_email') as string;

		if (!recipientEmail) {
			return fail(400, { error: 'Recipient email is required' });
		}

		// Get all active templates
		const { data: templates } = await supabaseAdmin
			.from('email_templates')
			.select('template_key')
			.eq('is_active', true);

		if (!templates || templates.length === 0) {
			return fail(400, { error: 'No active email templates found' });
		}

		let successCount = 0;
		let failCount = 0;
		const errors: string[] = [];

		for (const template of templates) {
			const testVariables = getTestVariables(template.template_key, member, url.origin);

			const result = await sendTemplatedEmail(template.template_key, recipientEmail, testVariables, {
				recipientId: member.id,
				recipientName: `${member.first_name} ${member.last_name}`,
				sentBy: member.id,
				baseUrl: url.origin
			});

			if (result.success) {
				successCount++;
			} else {
				failCount++;
				errors.push(`${template.template_key}: ${result.error}`);
			}

			// Small delay between emails to avoid rate limiting
			await new Promise((resolve) => setTimeout(resolve, 500));
		}

		if (failCount === 0) {
			return { success: `All ${successCount} test emails sent successfully!` };
		} else if (successCount === 0) {
			return fail(500, { error: `All emails failed to send. Errors: ${errors.join('; ')}` });
		} else {
			return {
				success: `Sent ${successCount} emails, ${failCount} failed.`,
				errors
			};
		}
	},

	/**
	 * Preview a template (returns HTML)
	 */
	previewTemplate: async ({ request, locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || member.role !== 'admin') {
			return fail(403, { error: 'Unauthorized' });
		}

		const formData = await request.formData();
		const templateKey = formData.get('template_key') as string;

		if (!templateKey) {
			return fail(400, { error: 'Template key is required' });
		}

		// Fetch the template
		const { data: template } = await supabaseAdmin
			.from('email_templates')
			.select('*')
			.eq('template_key', templateKey)
			.single();

		if (!template) {
			return fail(404, { error: 'Template not found' });
		}

		// Get test variables
		const testVariables = getTestVariables(templateKey, member, url.origin);
		const logoUrl = `${url.origin}/MONACOUSA-Flags_376x376.png`;

		// Replace variables in the template
		let html = template.body_html;
		let subject = template.subject;

		const allVariables: Record<string, string> = {
			logo_url: logoUrl,
			site_url: url.origin,
			...testVariables
		};

		for (const [key, value] of Object.entries(allVariables)) {
			const regex = new RegExp(`{{${key}}}`, 'g');
			html = html.replace(regex, value);
			subject = subject.replace(regex, value);
		}

		return {
			preview: {
				subject,
				html,
				templateName: template.name
			}
		};
	}
};

/**
 * Get test variables for different template types
 */
function getTestVariables(templateKey: string, member: any, baseUrl: string): Record<string, string> {
	const commonVars = {
		first_name: member.first_name || 'Test',
		last_name: member.last_name || 'User',
		member_name: `${member.first_name || 'Test'} ${member.last_name || 'User'}`,
		member_id: member.member_id || 'TEST-001',
		email: member.email || 'test@example.com',
		site_url: baseUrl,
		portal_url: baseUrl,
		logo_url: `${baseUrl}/MONACOUSA-Flags_376x376.png`
	};

	// Template-specific variables
	switch (templateKey) {
		case 'welcome':
			return {
				...commonVars,
				login_url: `${baseUrl}/login`
			};

		case 'payment_received':
			return {
				...commonVars,
				amount: '100.00',
				payment_date: new Date().toLocaleDateString('en-US', {
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				reference: 'TEST-REF-123',
				due_date: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				})
			};

		case 'dues_reminder_30':
		case 'dues_reminder_7':
		case 'dues_reminder_1':
			const daysMap: Record<string, string> = {
				dues_reminder_30: '30',
				dues_reminder_7: '7',
				dues_reminder_1: '1'
			};
			return {
				...commonVars,
				days_until_due: daysMap[templateKey] || '30',
				due_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				amount_due: '100.00',
				payment_url: `${baseUrl}/payments`,
				bank_name: 'Monaco Bank',
				iban: 'MC00 0000 0000 0000 0000 0000 000',
				bic: 'MONACOXX',
				payment_reference: `DUES-${member.member_id || 'TEST001'}`
			};

		case 'dues_overdue':
			return {
				...commonVars,
				days_overdue: '15',
				due_date: new Date(Date.now() - 15 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				amount_due: '100.00',
				payment_url: `${baseUrl}/payments`,
				bank_name: 'Monaco Bank',
				iban: 'MC00 0000 0000 0000 0000 0000 000',
				bic: 'MONACOXX',
				payment_reference: `DUES-${member.member_id || 'TEST001'}`
			};

		case 'dues_grace_warning':
			return {
				...commonVars,
				grace_days_remaining: '7',
				grace_end_date: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				amount_due: '100.00',
				payment_url: `${baseUrl}/payments`
			};

		case 'dues_inactive_notice':
			return {
				...commonVars,
				inactive_date: new Date().toLocaleDateString('en-US', {
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				reactivation_url: `${baseUrl}/payments`
			};

		case 'event_invitation':
			return {
				...commonVars,
				event_title: 'Monaco USA Annual Gala',
				event_date: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					weekday: 'long',
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				event_time: '7:00 PM',
				event_location: 'Hotel de Paris, Monaco',
				event_description: 'Join us for our annual celebration bringing together Americans living in Monaco.',
				event_url: `${baseUrl}/events/test-event`,
				rsvp_url: `${baseUrl}/events/test-event`
			};

		case 'event_reminder':
			return {
				...commonVars,
				event_title: 'Monaco USA Monthly Meetup',
				event_date: new Date(Date.now() + 1 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					weekday: 'long',
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				event_time: '6:00 PM',
				event_location: 'Stars n Bars, Monaco',
				event_url: `${baseUrl}/events/test-event`
			};

		case 'waitlist_promotion':
			return {
				...commonVars,
				event_title: 'Exclusive Wine Tasting Event',
				event_date: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', {
					weekday: 'long',
					month: 'long',
					day: 'numeric',
					year: 'numeric'
				}),
				event_time: '8:00 PM',
				event_location: 'Cave Princesse, Monaco',
				event_url: `${baseUrl}/events/test-event`,
				confirm_url: `${baseUrl}/events/test-event`
			};

		default:
			return commonVars;
	}
}
