/**
 * Cron API Endpoint for Automated Dues Reminders
 *
 * This endpoint should be called daily by an external cron service
 * (e.g., Vercel Cron, GitHub Actions, or a server cron job)
 *
 * Security: Requires CRON_SECRET header for authentication
 *
 * Example cron setup (daily at 9 AM):
 * 0 9 * * * curl -X POST https://yourdomain.com/api/cron/dues-reminders \
 *   -H "Authorization: Bearer YOUR_CRON_SECRET"
 */

import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { env } from '$env/dynamic/private';
import {
	getDuesSettings,
	sendBulkReminders,
	processGracePeriodExpirations,
	getMembersNeedingReminder,
	getMembersNeedingOnboardingReminder,
	sendOnboardingReminders,
	processOnboardingExpirations,
	type ReminderType,
	type OnboardingReminderType
} from '$lib/server/dues';

const CRON_SECRET = env.CRON_SECRET;

export const POST: RequestHandler = async ({ request, url }) => {
	// Verify cron secret
	const authHeader = request.headers.get('authorization');
	const token = authHeader?.replace('Bearer ', '');

	if (!CRON_SECRET) {
		console.error('CRON_SECRET not configured');
		return json({ error: 'Server not configured for cron jobs' }, { status: 500 });
	}

	if (token !== CRON_SECRET) {
		return json({ error: 'Unauthorized' }, { status: 401 });
	}

	const baseUrl = url.origin || env.SITE_URL || 'https://monacousa.org';
	const dryRun = url.searchParams.get('dry_run') === 'true';

	try {
		// Load reminder settings
		const settings = await getDuesSettings();
		const reminderDays = settings.reminder_days_before || [30, 7, 1];

		const results = {
			timestamp: new Date().toISOString(),
			dryRun,
			settings: {
				reminder_days_before: reminderDays,
				grace_period_days: settings.grace_period_days,
				auto_inactive_enabled: settings.auto_inactive_enabled
			},
			reminders: {
				due_soon_30: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] },
				due_soon_7: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] },
				due_soon_1: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] }
			} as Record<string, { eligible: number; sent: number; skipped: number; errors: string[] }>,
			overdue: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] },
			graceWarning: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] },
			// Onboarding reminders for new members with payment_deadline
			onboarding: {
				reminder_7: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] },
				reminder_1: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] },
				expired: { eligible: 0, sent: 0, skipped: 0, errors: [] as string[] }
			},
			inactivated: [] as Array<{ id: string; name: string; email: string }>,
			onboardingInactivated: [] as Array<{ id: string; name: string; email: string }>,
			summary: {
				totalRemindersSent: 0,
				totalErrors: 0
			}
		};

		// Process each reminder tier
		for (const days of reminderDays) {
			const reminderType = `due_soon_${days}` as ReminderType;

			// Get eligible members
			const eligibleMembers = await getMembersNeedingReminder(reminderType);
			results.reminders[reminderType] = {
				eligible: eligibleMembers.length,
				sent: 0,
				skipped: 0,
				errors: []
			};

			if (!dryRun && eligibleMembers.length > 0) {
				const result = await sendBulkReminders(reminderType, baseUrl);
				results.reminders[reminderType].sent = result.sent;
				results.reminders[reminderType].skipped = result.skipped;
				results.reminders[reminderType].errors = result.errors;
				results.summary.totalRemindersSent += result.sent;
				results.summary.totalErrors += result.errors.length;
			}
		}

		// Process overdue notifications
		const overdueMembers = await getMembersNeedingReminder('overdue');
		results.overdue.eligible = overdueMembers.length;

		if (!dryRun && overdueMembers.length > 0) {
			const overdueResult = await sendBulkReminders('overdue', baseUrl);
			results.overdue.sent = overdueResult.sent;
			results.overdue.skipped = overdueResult.skipped;
			results.overdue.errors = overdueResult.errors;
			results.summary.totalRemindersSent += overdueResult.sent;
			results.summary.totalErrors += overdueResult.errors.length;
		}

		// Process grace period warnings
		const graceMembers = await getMembersNeedingReminder('grace_period');
		results.graceWarning.eligible = graceMembers.length;

		if (!dryRun && graceMembers.length > 0) {
			const graceResult = await sendBulkReminders('grace_period', baseUrl);
			results.graceWarning.sent = graceResult.sent;
			results.graceWarning.skipped = graceResult.skipped;
			results.graceWarning.errors = graceResult.errors;
			results.summary.totalRemindersSent += graceResult.sent;
			results.summary.totalErrors += graceResult.errors.length;
		}

		// Process grace period expirations (mark members as inactive)
		if (!dryRun && settings.auto_inactive_enabled) {
			const inactivationResult = await processGracePeriodExpirations(baseUrl);
			results.inactivated = inactivationResult.members;
		}

		// ============================================
		// ONBOARDING REMINDERS (new members with payment_deadline)
		// ============================================

		// Process 7-day onboarding reminders
		const onboarding7Members = await getMembersNeedingOnboardingReminder('onboarding_reminder_7');
		results.onboarding.reminder_7.eligible = onboarding7Members.length;

		if (!dryRun && onboarding7Members.length > 0) {
			const onboarding7Result = await sendOnboardingReminders('onboarding_reminder_7', baseUrl);
			results.onboarding.reminder_7.sent = onboarding7Result.sent;
			results.onboarding.reminder_7.skipped = onboarding7Result.skipped;
			results.onboarding.reminder_7.errors = onboarding7Result.errors;
			results.summary.totalRemindersSent += onboarding7Result.sent;
			results.summary.totalErrors += onboarding7Result.errors.length;
		}

		// Process 1-day onboarding reminders (final warning)
		const onboarding1Members = await getMembersNeedingOnboardingReminder('onboarding_reminder_1');
		results.onboarding.reminder_1.eligible = onboarding1Members.length;

		if (!dryRun && onboarding1Members.length > 0) {
			const onboarding1Result = await sendOnboardingReminders('onboarding_reminder_1', baseUrl);
			results.onboarding.reminder_1.sent = onboarding1Result.sent;
			results.onboarding.reminder_1.skipped = onboarding1Result.skipped;
			results.onboarding.reminder_1.errors = onboarding1Result.errors;
			results.summary.totalRemindersSent += onboarding1Result.sent;
			results.summary.totalErrors += onboarding1Result.errors.length;
		}

		// Process expired onboarding deadlines (mark as inactive)
		if (!dryRun && settings.auto_inactive_enabled) {
			const onboardingExpiredResult = await processOnboardingExpirations(baseUrl);
			results.onboardingInactivated = onboardingExpiredResult.members;
		}

		return json(results);
	} catch (error) {
		console.error('Cron job error:', error);
		const errorMessage = error instanceof Error ? error.message : 'Unknown error';
		return json(
			{
				error: 'Internal server error',
				message: errorMessage,
				timestamp: new Date().toISOString()
			},
			{ status: 500 }
		);
	}
};

/**
 * GET endpoint for checking cron status and getting preview of pending actions
 */
export const GET: RequestHandler = async ({ request, url }) => {
	// Verify cron secret
	const authHeader = request.headers.get('authorization');
	const token = authHeader?.replace('Bearer ', '');

	if (!CRON_SECRET || token !== CRON_SECRET) {
		return json({ error: 'Unauthorized' }, { status: 401 });
	}

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

		const preview = {
			timestamp: new Date().toISOString(),
			settings: {
				reminder_days_before: reminderDays,
				grace_period_days: settings.grace_period_days,
				auto_inactive_enabled: settings.auto_inactive_enabled
			},
			pendingActions: {
				due_soon_30: 0,
				due_soon_7: 0,
				due_soon_1: 0,
				overdue: 0,
				grace_period: 0
			} as Record<string, number>,
			pendingOnboarding: {
				onboarding_reminder_7: 0,
				onboarding_reminder_1: 0,
				onboarding_expired: 0
			} as Record<string, number>
		};

		// Count pending for each type
		for (const days of reminderDays) {
			const reminderType = `due_soon_${days}` as ReminderType;
			const members = await getMembersNeedingReminder(reminderType);
			preview.pendingActions[reminderType] = members.length;
		}

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

		// Count grace period warnings
		const graceMembers = await getMembersNeedingReminder('grace_period');
		preview.pendingActions.grace_period = graceMembers.length;

		// Count onboarding reminders
		const onboarding7Members = await getMembersNeedingOnboardingReminder('onboarding_reminder_7');
		preview.pendingOnboarding.onboarding_reminder_7 = onboarding7Members.length;

		const onboarding1Members = await getMembersNeedingOnboardingReminder('onboarding_reminder_1');
		preview.pendingOnboarding.onboarding_reminder_1 = onboarding1Members.length;

		const onboardingExpiredMembers = await getMembersNeedingOnboardingReminder('onboarding_expired');
		preview.pendingOnboarding.onboarding_expired = onboardingExpiredMembers.length;

		return json(preview);
	} catch (error) {
		console.error('Cron preview error:', error);
		const errorMessage = error instanceof Error ? error.message : 'Unknown error';
		return json({ error: 'Internal server error', message: errorMessage }, { status: 500 });
	}
};
