import { weirdToNormalChars } from "weird-to-normal-chars";
import { MyStuff } from "@client/types/form/myStuff";
import { apiRoot, doNotSelect } from "@server/constants";
import { isLoggedIn } from "@server/middlewareButNotReally";
import { Review } from "@models/stories/review";
import { IUser, User } from "@models/user";
import axios from "axios";

function emsg(arg: string): any {
	return {
		statusCode: 400,
		message: `Could not update ${arg}`,
	};
}

export default eventHandler(async (ev) => {
	isLoggedIn(ev);
	const body = await readBody<MyStuff>(ev);
	let u = await User.findById(ev.context.currentUser!._id).select(doNotSelect).exec();
	if (!u) {
		throw createError({
			statusCode: 500,
			message: "this shouldn't happen.",
		});
	}
	let update: Partial<IUser> & any = {};
	if (body.email?.toLocaleLowerCase() !== u!.email) {
		if (u?.validPassword(body.password!)) {
			update.email = body.email;
		} else {
			throw createError(emsg("email"));
		}
	}
	if (body.password !== "" && body.newPassword) {
		if (u?.validPassword(body.password || "")) {
			update.password = User.generateHash(body.newPassword);
		} else {
			throw createError(emsg("password"));
		}
	}
	update["profile.disclaimer"] = body.disclaimer;
	update["profile.hidden"] = !!body.hidden;
	update["profile.nightMode"] = !!body.nightMode;
	update.notifyOnReviewReply = !!body.reviewReply;
	let nusername = weirdToNormalChars(body.username || u.username);
	if (nusername !== u.username) {
		let exists = await User.findOne({
			username: nusername,
		});
		if (exists) {
			throw createError(emsg("username"));
		}
		let { data: lookup } = await axios.get(`${apiRoot}/session-sharing/lookup`, {
			params: {
				id: ev.context.currentUser!._id,
			},
		});

		await axios.put(`${apiRoot}/v3/users/${lookup.value.uid}`, {
			body: {
				username: nusername,
				_uid: 1,
			},
			headers: {
				Authorization: `Bearer ${useRuntimeConfig().nodebb.masterToken}`,
			},
		});
		update.username = nusername;
		let regex = new RegExp(nusername, "g");
		await Review.collection.updateMany(
			{
				text: {
					$regex: regex,
				},
			},
			[
				{
					$set: {
						text: {
							$replaceAll: {
								input: "$text",
								find: u!.username,
								replacement: nusername,
							},
						},
					},
				},
			],
		);
	}
	u = await User.findByIdAndUpdate(
		ev.context.currentUser!._id,
		{
			$set: update,
		},
		{ new: true },
	);
	return {
		success: true,
		data: u,
	};
});
