import { invalid, redirect } from "@sveltejs/kit";
import { createUser, createSession, getUser } from "$lib/database";
import { MIN_USERNAME_LENGTH, MAX_USERNAME_LENGTH, USERNAME_REGEX, MIN_PASSWORD_LENGTH, INVITE_KEY_PREFIX, COOKIE_NAME, HCAPTCHA_SITEKEY } from "$lib/constants";

/** @type {import('./$types').Actions} */
export const actions = {
	default: async ({ cookies, request, getClientAddress }) => {
		const session = cookies.get(COOKIE_NAME);
		if (session) throw redirect(302, "/landing");

		const data = await request.formData();
		const username = data.get("username");
		const password = data.get("password");
		const confirm_password = data.get("confirm_password");
		const invite_key = data.get("invite_key");
		const hcaptcha_response = data.get("h-captcha-response");

		if (username.length < MIN_USERNAME_LENGTH || username.length > MAX_USERNAME_LENGTH || new RegExp(USERNAME_REGEX).test(username))
			return invalid(400, {
				username,
				invite_key,
				error: "username"
			});

		if (username.length < MIN_PASSWORD_LENGTH || confirm_password !== password)
			return invalid(400, {
				username,
				invite_key,
				error: "password"
			});

		if (!invite_key.startsWith(INVITE_KEY_PREFIX))
			return invalid(400, {
				username,
				invite_key,
				error: "invite_key"
			});

		if (!hcaptcha_response)
			return invalid(400, {
				username,
				invite_key,
				error: "hcaptcha"
			});

		const existingUser = await getUser({ username }, { _id: true });
		if (existingUser)
			return invalid(400, {
				username,
				invite_key,
				error: "username"
			});

		const hcaptcha = await fetch("https://hcaptcha.com/siteverify", {
			method: "POST",
			body: `response=${hcaptcha_response}&secret=${process.env.HCAPTCHA_SECRET}`,
			headers: { "content-type": "application/x-www-form-urlencoded" }
		});

		const hcaptchaBody = await hcaptcha.json();
		if (!hcaptchaBody.success)
			return invalid(400, {
				username,
				invite_key,
				error: "hcaptcha"
			});

		const user = await createUser(username, password, request.headers.get("x-forwarded-for") || getClientAddress());
		cookies.set(COOKIE_NAME, await createSession(user, request.headers.get("x-forwarded-for") || getClientAddress()), { secure: !!process.env.PRODUCTION });
		throw redirect(302, "/");
	}
};
