import { ApiClient } from '$lib/server/api';
import { validateToken } from '$lib/server/auth';
import { THEME_COOKIE, parseThemeCookie, themeToCss } from '$lib/theme/presets';
import { redirect, type Handle } from '@sveltejs/kit';
import { sequence } from '@sveltejs/kit/hooks';

const authHandle: Handle = async ({ event, resolve }) => {
	// Get auth token from cookies
	const authToken = event.cookies.get('authToken');

	if (authToken) {
		// Validate the token
		const api = new ApiClient(authToken);
		const user = await validateToken(api);

		if (user) {
			// Token is valid
			event.locals.user = user;
			event.locals.authToken = authToken;
			event.locals.api = api;
		} else {
			// Token invalid, clear auth cookie
			event.cookies.delete('authToken', { path: '/' });
		}
	}

	return resolve(event);
};

const protectedRoutesHandle: Handle = async ({ event, resolve }) => {
	const isProtectedRoute = !event.url.pathname.startsWith('/login');

	if (isProtectedRoute && !event.locals.user) throw redirect(303, '/login');

	return resolve(event);
};

/**
 * Inline the stored theme into the document head.
 *
 * The palette has to be in the very first byte of HTML the browser paints,
 * otherwise every page load flashes the default theme before hydration swaps
 * it. The `<!--theme-->` placeholder in app.html is the injection point.
 */
const themeHandle: Handle = async ({ event, resolve }) => {
	const config = parseThemeCookie(event.cookies.get(THEME_COOKIE));
	event.locals.theme = config;

	return resolve(event, {
		// The placeholder comment is kept, not replaced. Svelte 5 uses HTML
		// comments as hydration markers, so SvelteKit warns when a chunk comes
		// back with fewer comments than it went in with — removing this one is
		// enough to trip that check.
		transformPageChunk: ({ html }) =>
			html.replace(
				'<!--theme-->',
				`<!--theme--><style id="chitai-theme">${themeToCss(config)}</style>`
			)
	});
};

export const handle = sequence(themeHandle, authHandle, protectedRoutesHandle);
