import { fail } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
import { uploadAvatar, deleteAvatar } from '$lib/server/storage';
import { sendTemplatedEmail, wrapInMonacoTemplate, sendEmail } from '$lib/server/email';
import { getMailbox, updateMailbox, type PosteConfig } from '$lib/server/poste';

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

	// Load notification preferences
	const { data: notificationPrefs } = await locals.supabase
		.from('user_notification_preferences')
		.select('*')
		.eq('member_id', member.id)
		.single();

	// Check if member is board/admin and has a monacousa.org email
	let monacoEmail: string | null = null;
	let hasMonacoEmailAccount = false;

	if (member.role === 'board' || member.role === 'admin') {
		// Check if they have a monacousa.org email stored
		const { data: emailRecord } = await locals.supabase
			.from('members')
			.select('monaco_email')
			.eq('id', member.id)
			.single();

		if (emailRecord?.monaco_email) {
			monacoEmail = emailRecord.monaco_email;
			hasMonacoEmailAccount = true;
		} else if (member.email?.endsWith('@monacousa.org')) {
			// Their primary email is a monacousa.org email
			monacoEmail = member.email;
			hasMonacoEmailAccount = true;
		}
	}

	return {
		member,
		notificationPrefs: notificationPrefs || {
			email_event_rsvp_confirmation: true,
			email_event_reminder: true,
			email_event_updates: true,
			email_waitlist_promotion: true,
			email_dues_reminder: true,
			email_payment_confirmation: true,
			email_membership_updates: true,
			email_announcements: true,
			email_newsletter: true,
			newsletter_frequency: 'monthly'
		},
		monacoEmail,
		hasMonacoEmailAccount
	};
};

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

		if (!member) {
			return fail(401, { error: 'Not authenticated' });
		}

		const formData = await request.formData();
		const firstName = formData.get('first_name') as string;
		const lastName = formData.get('last_name') as string;
		const phone = formData.get('phone') as string;
		const address = formData.get('address') as string;
		const nationalityString = formData.get('nationality') as string;

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

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

		const nationality = nationalityString ? nationalityString.split(',').filter(Boolean) : [];

		// Update member profile
		const { error } = await locals.supabase
			.from('members')
			.update({
				first_name: firstName,
				last_name: lastName,
				phone: phone || null,
				address: address || null,
				nationality,
				updated_at: new Date().toISOString()
			})
			.eq('id', member.id);

		if (error) {
			console.error('Failed to update profile:', error);
			return fail(500, { error: 'Failed to update profile. Please try again.' });
		}

		return { success: 'Profile updated successfully!' };
	},

	uploadAvatar: async ({ request, locals }) => {
		const { member } = await locals.safeGetSession();

		if (!member) {
			return fail(401, { error: 'Not authenticated' });
		}

		const formData = await request.formData();
		const file = formData.get('avatar') as File;

		if (!file || !file.size) {
			return fail(400, { error: 'Please select an image to upload' });
		}

		// Validate file type
		const allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
		if (!allowedTypes.includes(file.type)) {
			return fail(400, { error: 'Please upload a valid image (JPEG, PNG, WebP, or GIF)' });
		}

		// Validate file size (max 5MB)
		if (file.size > 5 * 1024 * 1024) {
			return fail(400, { error: 'Image must be less than 5MB' });
		}

		// Upload the avatar - pass user's supabase client for RLS
		const result = await uploadAvatar(member.id, file, locals.supabase);

		if (!result.success) {
			return fail(400, { error: result.error || 'Failed to upload avatar' });
		}

		// Update member record with avatar URL
		const { error: updateError } = await locals.supabase
			.from('members')
			.update({
				avatar_url: result.publicUrl,
				updated_at: new Date().toISOString()
			})
			.eq('id', member.id);

		if (updateError) {
			console.error('Failed to update avatar URL:', updateError);
			return fail(500, { error: 'Failed to update profile with new avatar' });
		}

		return { success: 'Profile picture updated successfully!' };
	},

	removeAvatar: async ({ locals }) => {
		const { member } = await locals.safeGetSession();

		if (!member) {
			return fail(401, { error: 'Not authenticated' });
		}

		// Delete the avatar from storage - pass user's supabase client for RLS
		await deleteAvatar(member.id, locals.supabase);

		// Update member record to remove avatar URL
		const { error: updateError } = await locals.supabase
			.from('members')
			.update({
				avatar_url: null,
				updated_at: new Date().toISOString()
			})
			.eq('id', member.id);

		if (updateError) {
			console.error('Failed to remove avatar URL:', updateError);
			return fail(500, { error: 'Failed to update profile' });
		}

		return { success: 'Profile picture removed!' };
	},

	updateNotifications: async ({ request, locals }) => {
		const { member } = await locals.safeGetSession();

		if (!member) {
			return fail(401, { error: 'Not authenticated' });
		}

		const formData = await request.formData();

		const notificationPrefs = {
			email_event_rsvp_confirmation: formData.get('email_event_rsvp_confirmation') === 'on',
			email_event_reminder: formData.get('email_event_reminder') === 'on',
			email_event_updates: formData.get('email_event_updates') === 'on',
			email_waitlist_promotion: formData.get('email_waitlist_promotion') === 'on',
			email_dues_reminder: formData.get('email_dues_reminder') === 'on',
			email_payment_confirmation: formData.get('email_payment_confirmation') === 'on',
			email_membership_updates: formData.get('email_membership_updates') === 'on',
			email_announcements: formData.get('email_announcements') === 'on',
			email_newsletter: formData.get('email_newsletter') === 'on',
			newsletter_frequency: formData.get('newsletter_frequency') as string || 'monthly'
		};

		// Upsert notification preferences
		const { error } = await locals.supabase
			.from('user_notification_preferences')
			.upsert({
				member_id: member.id,
				...notificationPrefs,
				updated_at: new Date().toISOString()
			}, {
				onConflict: 'member_id'
			});

		if (error) {
			console.error('Failed to update notification preferences:', error);
			return fail(500, { error: 'Failed to update notification preferences' });
		}

		return { success: 'Notification preferences saved!' };
	},

	updateEmail: async ({ request, locals }) => {
		const { member, session } = await locals.safeGetSession();

		if (!member || !session) {
			return fail(401, { error: 'Not authenticated' });
		}

		const formData = await request.formData();
		const newEmail = formData.get('email') as string;

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

		if (newEmail === member.email) {
			return fail(400, { error: 'New email is the same as current email' });
		}

		// Update email in Supabase Auth (will send verification email)
		const { error } = await locals.supabase.auth.updateUser({
			email: newEmail
		});

		if (error) {
			console.error('Failed to update email:', error);
			if (error.message.includes('already registered')) {
				return fail(400, { error: 'This email is already in use by another account' });
			}
			return fail(500, { error: 'Failed to update email. Please try again.' });
		}

		return { success: 'Verification email sent to your new address. Please check your inbox.' };
	},

	updatePassword: async ({ request, locals }) => {
		const { member, session } = await locals.safeGetSession();

		if (!member || !session) {
			return fail(401, { error: 'Not authenticated' });
		}

		const formData = await request.formData();
		const currentPassword = formData.get('current_password') as string;
		const newPassword = formData.get('new_password') as string;
		const confirmPassword = formData.get('confirm_password') as string;

		// Validate current password is provided
		if (!currentPassword) {
			return fail(400, { error: 'Current password is required' });
		}

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

		if (newPassword !== confirmPassword) {
			return fail(400, { error: 'New passwords do not match' });
		}

		// Verify current password by re-authenticating
		const { error: authError } = await locals.supabase.auth.signInWithPassword({
			email: member.email,
			password: currentPassword
		});

		if (authError) {
			return fail(400, { error: 'Current password is incorrect' });
		}

		// Update password in Supabase Auth
		const { error } = await locals.supabase.auth.updateUser({
			password: newPassword
		});

		if (error) {
			console.error('Failed to update password:', error);
			return fail(500, { error: 'Failed to update password. Please try again.' });
		}

		// Send password changed notification email
		const changedAt = new Date().toLocaleString('en-US', {
			weekday: 'long',
			year: 'numeric',
			month: 'long',
			day: 'numeric',
			hour: '2-digit',
			minute: '2-digit',
			timeZoneName: 'short'
		});

		// Try to send templated email, fall back to inline email if template doesn't exist
		const templateResult = await sendTemplatedEmail(
			'password_changed',
			member.email,
			{
				first_name: member.first_name,
				changed_at: changedAt
			},
			{
				recipientId: member.id,
				recipientName: `${member.first_name} ${member.last_name}`
			}
		);

		// If template doesn't exist, send a fallback email
		if (!templateResult.success && templateResult.error?.includes('not found')) {
			const fallbackContent = `
				<p style="margin: 0 0 16px 0; color: #334155; line-height: 1.6;">Hi ${member.first_name},</p>
				<p style="margin: 0 0 16px 0; color: #334155; line-height: 1.6;">Your Monaco USA account password was successfully changed on <strong>${changedAt}</strong>.</p>
				<div style="background: #fef3c7; border: 1px solid #fbbf24; border-radius: 12px; padding: 20px; margin: 0 0 20px 0;">
					<p style="margin: 0 0 8px 0; color: #92400e; font-size: 14px; font-weight: 600;">⚠️ Didn't make this change?</p>
					<p style="margin: 0; color: #92400e; font-size: 14px;">If you did not change your password, please contact us immediately at <a href="mailto:info@monacousa.org" style="color: #92400e;">info@monacousa.org</a>.</p>
				</div>
				<p style="margin: 0; color: #64748b; font-size: 12px;">This is an automated security notification.</p>`;

			await sendEmail({
				to: member.email,
				subject: 'Your Monaco USA Password Was Changed',
				html: wrapInMonacoTemplate({
					title: 'Password Changed',
					content: fallbackContent
				}),
				recipientId: member.id,
				recipientName: `${member.first_name} ${member.last_name}`,
				emailType: 'account'
			});
		}

		return { success: 'Password updated successfully!' };
	},

	updateMonacoEmailPassword: async ({ request, locals }) => {
		const { member, session } = await locals.safeGetSession();

		if (!member || !session) {
			return fail(401, { error: 'Not authenticated' });
		}

		// Check if member has access to Monaco email
		if (member.role !== 'board' && member.role !== 'admin') {
			return fail(403, { error: 'Monaco email is only available for board members and admins' });
		}

		const formData = await request.formData();
		const monacoEmail = formData.get('monaco_email') as string;
		const newPassword = formData.get('monaco_new_password') as string;
		const confirmPassword = formData.get('monaco_confirm_password') as string;

		if (!monacoEmail || !monacoEmail.endsWith('@monacousa.org')) {
			return fail(400, { error: 'Invalid Monaco USA email address' });
		}

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

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

		// Get Poste configuration from app_settings
		const { data: posteSettings } = await locals.supabase
			.from('app_settings')
			.select('setting_key, setting_value')
			.eq('category', 'poste');

		if (!posteSettings || posteSettings.length === 0) {
			return fail(500, { error: 'Email server not configured. Please contact an administrator.' });
		}

		const config: PosteConfig = {
			host: '',
			adminEmail: '',
			adminPassword: ''
		};

		for (const setting of posteSettings) {
			let value = setting.setting_value;
			if (typeof value === 'string') {
				value = value.replace(/^"|"$/g, '');
			}
			if (setting.setting_key === 'poste_api_host') config.host = value as string;
			if (setting.setting_key === 'poste_admin_email') config.adminEmail = value as string;
			if (setting.setting_key === 'poste_admin_password') config.adminPassword = value as string;
		}

		if (!config.host || !config.adminEmail || !config.adminPassword) {
			return fail(500, { error: 'Email server not properly configured. Please contact an administrator.' });
		}

		// Update the mailbox password
		const result = await updateMailbox(config, monacoEmail, { password: newPassword });

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

		return { success: 'Monaco USA email password updated successfully!' };
	}
};
