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

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

	// If already logged in, check if onboarding is completed
	if (session) {
		// Get member profile to check onboarding status
		const { data: member } = await locals.supabase
			.from('members')
			.select('onboarding_completed_at')
			.eq('id', session.user.id)
			.single();

		// Only redirect to dashboard if onboarding is completed
		if (member?.onboarding_completed_at) {
			throw redirect(303, '/dashboard');
		}
		// Otherwise, let them continue the onboarding wizard
	}

	// Get payment settings for the payment step
	const { data: settings } = await locals.supabase
		.from('app_settings')
		.select('setting_key, setting_value')
		.eq('category', 'dues');

	const paymentSettings: Record<string, string> = {};
	if (settings) {
		for (const s of settings) {
			let value = s.setting_value;
			if (typeof value === 'string') {
				value = value.replace(/^"|"$/g, '');
			}
			paymentSettings[s.setting_key.replace('payment_', '')] = value as string;
		}
	}

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

	// If logged in but not completed onboarding, get member data
	let member = null;
	if (session) {
		const { data } = await locals.supabase
			.from('members')
			.select('id, first_name, email, member_id')
			.eq('id', session.user.id)
			.single();
		member = data;
	}

	return {
		paymentSettings,
		duesAmount: defaultType?.annual_dues || 150,
		session: session || null,
		member
	};
};

export const actions: Actions = {
	createAccount: async ({ request, locals, url }) => {
		const formData = await request.formData();

		// Extract form fields
		const firstName = formData.get('first_name') as string;
		const lastName = formData.get('last_name') as string;
		const email = formData.get('email') as string;
		const phone = formData.get('phone') as string;
		const dateOfBirth = formData.get('date_of_birth') as string;
		const address = formData.get('address') as string;
		const nationalityString = formData.get('nationality') as string;
		const password = formData.get('password') as string;
		const confirmPassword = formData.get('confirm_password') as string;
		const terms = formData.get('terms');

		// Validation
		if (!firstName || firstName.length < 2) {
			return fail(400, { error: 'First name must be at least 2 characters', step: 2 });
		}

		if (!lastName || lastName.length < 2) {
			return fail(400, { error: 'Last name must be at least 2 characters', step: 2 });
		}

		if (!email || !email.includes('@')) {
			return fail(400, { error: 'Please enter a valid email address', step: 2 });
		}

		if (!phone) {
			return fail(400, { error: 'Phone number is required', step: 2 });
		}

		if (!dateOfBirth) {
			return fail(400, { error: 'Date of birth is required', step: 2 });
		} else {
			// Check if 18+
			const birthDate = new Date(dateOfBirth);
			const today = new Date();
			const age = today.getFullYear() - birthDate.getFullYear();
			const monthDiff = today.getMonth() - birthDate.getMonth();
			const dayDiff = today.getDate() - birthDate.getDate();
			const actualAge = monthDiff < 0 || (monthDiff === 0 && dayDiff < 0) ? age - 1 : age;

			if (actualAge < 18) {
				return fail(400, { error: 'You must be at least 18 years old to join', step: 2 });
			}
		}

		if (!address || address.length < 10) {
			return fail(400, { error: 'Please enter a complete address', step: 2 });
		}

		const nationality = nationalityString ? nationalityString.split(',').filter(Boolean) : [];
		if (nationality.length === 0) {
			return fail(400, { error: 'Please select at least one nationality', step: 2 });
		}

		if (!password || password.length < 8) {
			return fail(400, { error: 'Password must be at least 8 characters', step: 2 });
		}

		if (password !== confirmPassword) {
			return fail(400, { error: 'Passwords do not match', step: 2 });
		}

		if (!terms) {
			return fail(400, { error: 'You must accept the terms and conditions', step: 2 });
		}

		// Create Supabase auth user
		const { data: authData, error: authError } = await locals.supabase.auth.signUp({
			email,
			password,
			options: {
				emailRedirectTo: `${url.origin}/join?verified=true`,
				data: {
					first_name: firstName,
					last_name: lastName
				}
			}
		});

		if (authError) {
			if (authError.message.includes('already registered')) {
				return fail(400, {
					error: 'An account with this email already exists. Try signing in instead.',
					step: 2
				});
			}
			return fail(400, { error: authError.message, step: 2 });
		}

		if (!authData.user) {
			return fail(500, { error: 'Failed to create account. Please try again.', step: 2 });
		}

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

		// Get the default membership type
		const { data: defaultType } = await locals.supabase
			.from('membership_types')
			.select('id')
			.eq('is_default', true)
			.single();

		if (!pendingStatus?.id || !defaultType?.id) {
			console.error('Missing default status or type');
			await supabaseAdmin.auth.admin.deleteUser(authData.user.id);
			return fail(500, { error: 'System configuration error. Please contact support.', step: 2 });
		}

		// Generate member ID
		const year = new Date().getFullYear();
		const { count } = await locals.supabase
			.from('members')
			.select('*', { count: 'exact', head: true });

		const memberNumber = String((count || 0) + 1).padStart(4, '0');
		const memberId = `MUSA-${year}-${memberNumber}`;

		// Create member profile
		const { error: memberError } = await locals.supabase.from('members').insert({
			id: authData.user.id,
			first_name: firstName,
			last_name: lastName,
			email,
			phone,
			date_of_birth: dateOfBirth,
			address,
			nationality,
			member_id: memberId,
			role: 'member',
			membership_status_id: pendingStatus.id,
			membership_type_id: defaultType.id
		});

		if (memberError) {
			console.error('Failed to create member profile:', memberError);
			try {
				await supabaseAdmin.auth.admin.deleteUser(authData.user.id);
			} catch (deleteError) {
				console.error('Failed to clean up auth user:', deleteError);
			}
			return fail(500, {
				error: 'Failed to create member profile. Please try again.',
				step: 2
			});
		}

		// Sign in the user so they can continue the wizard
		const { error: signInError } = await locals.supabase.auth.signInWithPassword({
			email,
			password
		});

		if (signInError) {
			console.error('Failed to sign in after account creation:', signInError);
			// Continue anyway - they can verify email and sign in later
		}

		return {
			success: true,
			step: 2,
			memberId,
			email
		};
	},

	uploadPhoto: async ({ request, locals }) => {
		const { session } = await locals.safeGetSession();
		if (!session) {
			return fail(401, { error: 'Not authenticated', step: 3 });
		}

		// For now, just proceed to next step
		// Avatar upload can be handled via the profile page later
		// or we can add proper file handling here

		return {
			success: true,
			step: 3
		};
	},

	complete: async ({ locals }) => {
		const { session } = await locals.safeGetSession();
		if (!session) {
			return fail(401, { error: 'Not authenticated', step: 6 });
		}

		// Set payment deadline (30 days from now)
		const paymentDeadline = new Date();
		paymentDeadline.setDate(paymentDeadline.getDate() + 30);

		// Update member with onboarding completion
		const { error: updateError } = await locals.supabase
			.from('members')
			.update({
				payment_deadline: paymentDeadline.toISOString(),
				onboarding_completed_at: new Date().toISOString()
			})
			.eq('id', session.user.id);

		if (updateError) {
			console.error('Failed to update member:', updateError);
			return fail(500, { error: 'Failed to complete onboarding', step: 6 });
		}

		// Get member data for email
		const { data: member } = await locals.supabase
			.from('members')
			.select('first_name, member_id, email')
			.eq('id', session.user.id)
			.single();

		// Get payment settings
		const { data: settings } = await locals.supabase
			.from('app_settings')
			.select('setting_key, setting_value')
			.eq('category', 'dues');

		const paymentSettings: Record<string, string> = {};
		if (settings) {
			for (const s of settings) {
				let value = s.setting_value;
				if (typeof value === 'string') {
					value = value.replace(/^"|"$/g, '');
				}
				paymentSettings[s.setting_key.replace('payment_', '')] = value as string;
			}
		}

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

		// Send welcome email with payment instructions
		if (member) {
			try {
				await sendTemplatedEmail(
					'onboarding_welcome',
					member.email,
					{
						first_name: member.first_name,
						member_id: member.member_id || 'N/A',
						amount: `€${defaultType?.annual_dues || 150}`,
						payment_deadline: paymentDeadline.toLocaleDateString('en-US', {
							weekday: 'long',
							year: 'numeric',
							month: 'long',
							day: 'numeric'
						}),
						account_holder: paymentSettings.account_holder || 'Monaco USA',
						bank_name: paymentSettings.bank_name || 'Credit Foncier de Monaco',
						iban: paymentSettings.iban || 'Contact for details'
					},
					{
						recipientId: session.user.id,
						recipientName: `${member.first_name}`,
						sentBy: 'system'
					}
				);
			} catch (emailError) {
				console.error('Failed to send welcome email:', emailError);
				// Continue anyway - not critical
			}
		}

		return {
			success: true,
			step: 6
		};
	}
};
