import { ApiError, getJavaUuid, getNoAuthUuid, UserNotFoundError } from '$lib/server/minecraft';
import { error, type RequestHandler } from '@sveltejs/kit';
import { Settings, User } from '$lib/server/database';

export const POST = (async ({ request }) => {
	// eslint-disable-next-line @typescript-eslint/ban-ts-comment
	// @ts-expect-error
	if ((await Settings.findOne({ where: { key: 'register.enabled' } }))?.value === false) {
		throw error(400, 'Anmeldung geschlossen');
	}

	const data = await request.formData();
	const firstname = data.get('firstname') as string | null;
	const lastname = data.get('lastname') as string | null;
	const birthday: number = Date.parse(data.get('birthday') as string);
	const telephone = data.get('telephone') as string | null;
	const username = data.get('username') as string | null;
	const playertype = data.get('playertype') as string | null;
	const password = data.get('password') as string | null;

	if (
		firstname == null ||
		lastname == null ||
		Number.isNaN(birthday) ||
		username == null ||
		playertype == null
	) {
		throw error(400, 'Ungültige Parameter');
	}

	let uuid: string | null;
	try {
		// available playertypes are 'java', 'bedrock' and 'noauth'
		switch (data.get('playertype')) {
			case 'java':
				uuid = await getJavaUuid(username);
				break;
			case 'bedrock':
				uuid = null;
				// uuid = await getBedrockUuid(username);
				break;
			case 'noauth':
				uuid = getNoAuthUuid(username);
				break;
			default:
				throw new Error(`invalid player type (${playertype})`);
		}
	} catch (e) {
		if (e instanceof UserNotFoundError) {
			throw error(
				400,
				"Der Spielername '" +
					username +
					"' existiert nicht. Hast Du Deinen Spielernamen korrekt geschrieben " +
					'und besitzt Du einen Minecraft-Account?\n\nKontaktiere bitte einen Admin, falls Du Dich trotz korrekter ' +
					'Angabe nicht registrieren kannst.'
			);
		} else if (e instanceof ApiError) {
			console.error((e as Error).message);
			uuid = null;
		} else {
			console.error((e as Error).message);
			throw error(500);
		}
	}

	if (uuid && (await User.findOne({ where: { uuid: uuid } }))) {
		throw error(
			400,
			'Dein Minecraft-Account wurde bereits registriert.\n\nKontaktiere bitte einen Admin, falls diese ' +
				'Informationen für Dich fehlerhaft erscheinen oder Du Angaben Deiner bestehenden Registrierung verändern ' +
				'möchtest.'
		);
	} else if (
		await User.findOne({
			where: {
				firstname: firstname,
				lastname: lastname,
				birthday: new Date(birthday).toUTCString()
			}
		})
	) {
		throw error(
			400,
			'In Deinem Namen wurde bereits ein Minecraft-Account registriert. Es ist nur ein Account pro Spieler ' +
				'erlaubt.\n\nKontaktiere bitte einen Admin, falls diese Informationen für Dich fehlerhaft erscheinen oder ' +
				'Du Angaben Deiner bestehenden Registrierung verändern möchtest.'
		);
	}

	await User.create({
		firstname: firstname,
		lastname: lastname,
		birthday: new Date(birthday).toUTCString(),
		telephone: telephone,
		username: username,
		playertype: playertype,
		password: password,
		uuid: uuid
	});

	return new Response();
}) satisfies RequestHandler;
