import { fail } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
import { sendTemplatedEmail } from '$lib/server/email';
import { logPaymentAction } from '$lib/server/audit';
import {
	sendBulkReminders,
	sendDuesReminder,
	getMembersNeedingReminder,
	getDuesSettings,
	type ReminderType
} from '$lib/server/dues';
import { supabaseAdmin } from '$lib/server/supabase';

export const load: PageServerLoad = async ({ locals, url }) => {
	const statusFilter = url.searchParams.get('status') || 'all';
	const searchQuery = url.searchParams.get('search') || '';
	const memberId = url.searchParams.get('member') || null;

	// If specific member requested, load their details
	let selectedMember = null;
	if (memberId) {
		const { data } = await locals.supabase
			.from('members_with_dues')
			.select('*')
			.eq('id', memberId)
			.single();
		selectedMember = data;
	}

	// Load all members with dues status
	const { data: members } = await locals.supabase
		.from('members_with_dues')
		.select('*')
		.order('last_name', { ascending: true });

	// Filter by dues status
	let filteredMembers = members || [];
	if (statusFilter !== 'all') {
		filteredMembers = filteredMembers.filter((m: any) => m.dues_status === statusFilter);
	}

	// Filter by search
	if (searchQuery) {
		const lowerSearch = searchQuery.toLowerCase();
		filteredMembers = filteredMembers.filter(
			(m: any) =>
				m.first_name?.toLowerCase().includes(lowerSearch) ||
				m.last_name?.toLowerCase().includes(lowerSearch) ||
				m.member_id?.toLowerCase().includes(lowerSearch)
		);
	}

	// Calculate stats
	const stats = {
		total: members?.length || 0,
		current: members?.filter((m: any) => m.dues_status === 'current').length || 0,
		dueSoon: members?.filter((m: any) => m.dues_status === 'due_soon').length || 0,
		overdue: members?.filter((m: any) => m.dues_status === 'overdue').length || 0,
		neverPaid: members?.filter((m: any) => m.dues_status === 'never_paid').length || 0
	};

	// Get recent payments
	const { data: recentPayments } = await locals.supabase
		.from('dues_payments')
		.select(
			`
			*,
			member:members(id, first_name, last_name, member_id),
			recorder:members!dues_payments_recorded_by_fkey(first_name, last_name)
		`
		)
		.order('created_at', { ascending: false })
		.limit(10);

	// Get membership types for payment recording
	const { data: membershipTypes } = await locals.supabase
		.from('membership_types')
		.select('*')
		.eq('is_active', true)
		.order('sort_order', { ascending: true });

	return {
		members: filteredMembers,
		selectedMember,
		stats,
		recentPayments: recentPayments || [],
		membershipTypes: membershipTypes || [],
		filters: {
			status: statusFilter,
			search: searchQuery,
			memberId
		}
	};
};

export const actions: Actions = {
	recordPayment: async ({ request, locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || (member.role !== 'board' && member.role !== 'admin')) {
			return fail(403, { error: 'You do not have permission to record payments' });
		}

		const formData = await request.formData();
		const memberId = formData.get('member_id') as string;
		const amount = parseFloat(formData.get('amount') as string);
		const paymentDate = formData.get('payment_date') as string;
		const paymentMethod = formData.get('payment_method') as string;
		const reference = formData.get('reference') as string;
		const notes = formData.get('notes') as string;
		const sendNotification = formData.get('send_notification') === 'on';

		if (!memberId || !amount || !paymentDate) {
			return fail(400, { error: 'Member, amount, and payment date are required' });
		}

		// Get member details for notification
		const { data: payingMember } = await locals.supabase
			.from('members')
			.select('first_name, last_name, email')
			.eq('id', memberId)
			.single();

		// Calculate due date (1 year from payment date)
		const dueDate = new Date(paymentDate);
		dueDate.setFullYear(dueDate.getFullYear() + 1);
		const dueDateStr = dueDate.toISOString().split('T')[0];

		// Record the payment
		const { data: paymentData, error: paymentError } = await locals.supabase
			.from('dues_payments')
			.insert({
				member_id: memberId,
				amount,
				payment_date: paymentDate,
				due_date: dueDateStr,
				payment_method: paymentMethod || 'bank_transfer',
				reference: reference || null,
				notes: notes || null,
				recorded_by: member.id
			})
			.select('id')
			.single();

		if (paymentError) {
			console.error('Payment recording error:', paymentError);
			return fail(500, { error: 'Failed to record payment. Please try again.' });
		}

		// Log audit
		await logPaymentAction(
			'record',
			{ id: member.id, email: member.email },
			{ id: paymentData?.id, memberId, amount },
			{ payment_date: paymentDate, payment_method: paymentMethod }
		);

		// Send email notification if requested
		if (sendNotification && payingMember?.email) {
			const formattedDate = new Date(paymentDate).toLocaleDateString('en-US', {
				month: 'long',
				day: 'numeric',
				year: 'numeric'
			});
			const formattedDueDate = dueDate.toLocaleDateString('en-US', {
				month: 'long',
				day: 'numeric',
				year: 'numeric'
			});

			await sendTemplatedEmail(
				'payment_received',
				payingMember.email,
				{
					first_name: payingMember.first_name,
					amount: amount.toFixed(2),
					payment_date: formattedDate,
					reference: reference || 'N/A',
					due_date: formattedDueDate
				},
				{
					recipientId: memberId,
					recipientName: `${payingMember.first_name} ${payingMember.last_name}`,
					sentBy: member.id,
					baseUrl: url.origin
				}
			);
		}

		return { success: 'Payment recorded successfully!' + (sendNotification ? ' Notification sent.' : '') };
	},

	/**
	 * Send individual reminder to a specific member
	 */
	sendReminder: async ({ request, locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || (member.role !== 'board' && member.role !== 'admin')) {
			return fail(403, { error: 'You do not have permission to send reminders' });
		}

		const formData = await request.formData();
		const memberId = formData.get('member_id') as string;
		const reminderType = formData.get('reminder_type') as ReminderType;

		if (!memberId) {
			return fail(400, { error: 'Member ID is required' });
		}

		// Get member details
		const { data: targetMember } = await supabaseAdmin
			.from('members_with_dues')
			.select('*')
			.eq('id', memberId)
			.single();

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

		// Determine the appropriate reminder type based on their status
		let effectiveReminderType = reminderType;
		if (!effectiveReminderType) {
			if (targetMember.dues_status === 'overdue') {
				effectiveReminderType = 'overdue';
			} else if (targetMember.dues_status === 'due_soon') {
				effectiveReminderType = 'due_soon_7';
			} else {
				effectiveReminderType = 'due_soon_30';
			}
		}

		const result = await sendDuesReminder(targetMember, effectiveReminderType, url.origin);

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

		return {
			success: `Reminder sent to ${targetMember.first_name} ${targetMember.last_name}`
		};
	},

	/**
	 * Send bulk reminders to all members in due_soon status
	 */
	sendBulkDueSoonReminders: async ({ locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || (member.role !== 'board' && member.role !== 'admin')) {
			return fail(403, { error: 'You do not have permission to send bulk reminders' });
		}

		const results = {
			due_soon_30: { sent: 0, errors: [] as string[] },
			due_soon_7: { sent: 0, errors: [] as string[] },
			due_soon_1: { sent: 0, errors: [] as string[] }
		};

		// Get settings to determine which reminder tiers to process
		const settings = await getDuesSettings();
		const reminderDays = settings.reminder_days_before || [30, 7, 1];

		let totalSent = 0;
		const allErrors: string[] = [];

		for (const days of reminderDays) {
			const reminderType = `due_soon_${days}` as ReminderType;
			const result = await sendBulkReminders(reminderType, url.origin);

			results[reminderType as keyof typeof results] = {
				sent: result.sent,
				errors: result.errors
			};
			totalSent += result.sent;
			allErrors.push(...result.errors);
		}

		if (totalSent === 0 && allErrors.length === 0) {
			return { success: 'No members need due soon reminders at this time.' };
		}

		const errorMsg = allErrors.length > 0 ? ` (${allErrors.length} errors)` : '';
		return {
			success: `Sent ${totalSent} due soon reminder(s)${errorMsg}`,
			bulkResult: results
		};
	},

	/**
	 * Send bulk reminders to all overdue members
	 */
	sendBulkOverdueReminders: async ({ locals, url }) => {
		const { member } = await locals.safeGetSession();

		if (!member || (member.role !== 'board' && member.role !== 'admin')) {
			return fail(403, { error: 'You do not have permission to send bulk reminders' });
		}

		const result = await sendBulkReminders('overdue', url.origin);

		if (result.sent === 0 && result.errors.length === 0) {
			return { success: 'No overdue members need reminders at this time.' };
		}

		const errorMsg = result.errors.length > 0 ? ` (${result.errors.length} errors)` : '';
		return {
			success: `Sent ${result.sent} overdue reminder(s)${errorMsg}`,
			bulkResult: result
		};
	},

	/**
	 * Get preview counts for bulk operations
	 */
	getBulkPreview: async ({ locals }) => {
		const { member } = await locals.safeGetSession();

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

		const settings = await getDuesSettings();
		const reminderDays = settings.reminder_days_before || [30, 7, 1];

		const preview = {
			dueSoon: 0,
			overdue: 0,
			breakdown: {} as Record<string, number>
		};

		for (const days of reminderDays) {
			const reminderType = `due_soon_${days}` as ReminderType;
			const members = await getMembersNeedingReminder(reminderType);
			preview.breakdown[reminderType] = members.length;
			preview.dueSoon += members.length;
		}

		const overdueMembers = await getMembersNeedingReminder('overdue');
		preview.overdue = overdueMembers.length;

		return { preview };
	}
};
