import { fail, redirect, type Actions } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { extractFaSessionId } from '$lib/shared/cookies';
import { getErrorMessage, type ErrorCode } from '$lib/shared/errors';
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = ({ url }) => {
	return {
		registered: url.searchParams.get('registered') === '1',
		reason: url.searchParams.get('reason')
	};
};

export const actions = {
	login: async ({ request, cookies, fetch, url }) => {
		const data = await request.formData();
		const email = data.get('email') as string;
		const password = data.get('password') as string;

		if (!email || !password) {
			return fail(400, { error: getErrorMessage('MISSING_CREDENTIALS') });
		}

		const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
		let response: Response;
		try {
			response = await fetch(`${baseUrl}/api/auth/login`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ email, password })
			});
		} catch (e) {
			console.error('Login request failed', e);
			return fail(500, { error: getErrorMessage('INTERNAL_ERROR') });
		}

		if (response.status === 401) {
			let code: ErrorCode = 'INVALID_CREDENTIALS';
			try {
				const body = (await response.json()) as { code?: string };
				if (body?.code) code = body.code as ErrorCode;
			} catch {
				// Body not JSON — fall through to INVALID_CREDENTIALS
			}
			return fail(401, { error: getErrorMessage(code) });
		}

		if (response.status === 429) {
			return fail(429, { error: getErrorMessage('TOO_MANY_LOGIN_ATTEMPTS'), rateLimited: true });
		}

		if (!response.ok) {
			return fail(response.status, { error: getErrorMessage('INTERNAL_ERROR') });
		}

		// Extract fa_session id from the Set-Cookie header and re-emit to the browser.
		// Modern Node/Undici exposes getSetCookie(); fall back to a single header for older runtimes.
		const setCookieHeaders =
			typeof response.headers.getSetCookie === 'function'
				? response.headers.getSetCookie()
				: response.headers.get('set-cookie')
					? [response.headers.get('set-cookie')!]
					: [];
		const sessionId = extractFaSessionId(setCookieHeaders);
		if (!sessionId) {
			console.error('Backend returned 200 OK on login but no fa_session cookie');
			return fail(500, { error: getErrorMessage('INTERNAL_ERROR') });
		}

		const isHttps = url.protocol === 'https:';
		cookies.set('fa_session', sessionId, {
			path: '/',
			httpOnly: true,
			sameSite: 'strict',
			secure: isHttps,
			maxAge: 60 * 60 * 8 // 8h — must match backend spring.session.timeout
		});

		// Best-effort cleanup of the legacy Basic-auth cookie from older deployments.
		cookies.delete('auth_token', { path: '/' });

		return redirect(303, '/');
	}
} satisfies Actions;
