import { json } from '@sveltejs/kit';
import type { RequestHandler } from '@sveltejs/kit';
import {
	authenticateLocal,
	authenticateLdap,
	getEnabledLdapConfigs,
	createUserSession,
	isRateLimited,
	recordFailedAttempt,
	clearRateLimit,
	verifyMfaToken,
	isAuthEnabled
} from '$lib/server/auth';
import { getUser, getUserByUsername } from '$lib/server/db';

// POST /api/auth/login - Authenticate user
export const POST: RequestHandler = async ({ request, cookies, getClientAddress }) => {
	// Check if auth is enabled
	if (!(await isAuthEnabled())) {
		return json({ error: 'Authentication is not enabled' }, { status: 400 });
	}

	try {
		const { username, password, mfaToken, provider = 'local' } = await request.json();

		if (!username || !password) {
			return json({ error: 'Username and password are required' }, { status: 400 });
		}

		// Rate limiting by IP and username
		const clientIp = getClientAddress();
		const rateLimitKey = `${clientIp}:${username}`;

		const { limited, retryAfter } = isRateLimited(rateLimitKey);
		if (limited) {
			return json(
				{ error: `Too many login attempts. Please try again in ${retryAfter} seconds.` },
				{ status: 429 }
			);
		}

		// Attempt authentication based on provider
		let result: any;
		let authProviderType: 'local' | 'ldap' | 'oidc' = 'local';

		if (provider.startsWith('ldap:')) {
			// LDAP provider with specific config ID (e.g., "ldap:1")
			const configId = parseInt(provider.split(':')[1], 10);
			result = await authenticateLdap(username, password, configId);
			authProviderType = 'ldap';
		} else if (provider === 'ldap') {
			// Generic LDAP (will try all enabled configs)
			result = await authenticateLdap(username, password);
			authProviderType = 'ldap';
		} else {
			result = await authenticateLocal(username, password);
			authProviderType = 'local';
		}

		if (!result.success) {
			recordFailedAttempt(rateLimitKey);
			return json({ error: result.error || 'Authentication failed' }, { status: 401 });
		}

		// Handle MFA if required
		if (result.requiresMfa) {
			if (!mfaToken) {
				// Return that MFA is required
				return json({ requiresMfa: true }, { status: 200 });
			}

			// Verify MFA token
			const user = await getUserByUsername(username);
			if (!user || !(await verifyMfaToken(user.id, mfaToken))) {
				recordFailedAttempt(rateLimitKey);
				return json({ error: 'Invalid MFA code' }, { status: 401 });
			}

			// MFA verified, create session
			const session = await createUserSession(user.id, authProviderType, cookies);
			clearRateLimit(rateLimitKey);

			return json({
				success: true,
				user: {
					id: user.id,
					username: user.username,
					email: user.email,
					displayName: user.displayName,
					isAdmin: user.isAdmin
				}
			});
		}

		// No MFA, create session directly
		if (result.user) {
			const session = await createUserSession(result.user.id, authProviderType, cookies);
			clearRateLimit(rateLimitKey);

			return json({
				success: true,
				user: {
					id: result.user.id,
					username: result.user.username,
					email: result.user.email,
					displayName: result.user.displayName,
					isAdmin: result.user.isAdmin
				}
			});
		}

		return json({ error: 'Authentication failed' }, { status: 401 });
	} catch (error) {
		console.error('Login error:', error);
		return json({ error: 'Login failed' }, { status: 500 });
	}
};
