import { logger } from "../logger/index.mjs";
import { formatResponse } from "../utils/responseData.mjs";
import { ErrorHandler } from "../utils/errors/ErrorHandler.mjs";
import { hasPermission } from "../utils/permissions.mjs";
import { createUser, getUserByEmail, getUserById, updateUserById } from "../services/user.service.mjs";
import { mapUserToAPI } from "../utils/mapper/user.mjs";
import { t } from "express-intlayer";

//#region src/controllers/newsletter.controller.ts
/**
* Subscribes a user to the newsletter.
* If the user doesn't exist, creates a new user.
* If the user exists, updates their newsletter subscription to true.
*/
const subscribeToNewsletter = async (req, res, _next) => {
	const { roles } = res.locals;
	const { email, emailList } = req.body;
	if (!email) {
		ErrorHandler.handleGenericErrorResponse(res, "USER_DATA_NOT_FOUND");
		return;
	}
	const emailLists = Array.isArray(emailList) ? emailList : [emailList];
	const emailsListObject = Object.fromEntries(emailLists.map((list) => [list, true]));
	try {
		let user = await getUserByEmail(email);
		if (!user) {
			user = await createUser({
				email,
				emailsList: emailsListObject
			});
			logger.info(`New user created and subscribed to newsletter: ${email}`);
		} else {
			if (!hasPermission(roles, "user:write")({
				...res.locals,
				targetUsers: [user]
			})) {
				ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
				return;
			}
			user = await updateUserById(user.id, { emailsList: {
				...user.emailsList,
				...emailsListObject
			} });
			logger.info(`User subscribed to newsletter: ${email}`);
		}
		const formattedUser = mapUserToAPI(user);
		const responseData = formatResponse({
			message: t({
				en: "Successfully subscribed to newsletter",
				fr: "Abonnement à la newsletter réussi",
				es: "Suscripción al boletín exitosa"
			}),
			description: t({
				en: "You have been successfully subscribed to our newsletter",
				fr: "Vous avez été abonné avec succès à notre newsletter",
				es: "Te has suscrito exitosamente a nuestro boletín"
			}),
			data: formattedUser
		});
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Unsubscribes a user from the newsletter.
* Only works if the user exists.
*/
const unsubscribeFromNewsletter = async (req, res, _next) => {
	const { userId, emailList } = req.body;
	const { roles } = res.locals;
	if (!userId) {
		ErrorHandler.handleGenericErrorResponse(res, "USER_DATA_NOT_FOUND");
		return;
	}
	try {
		const user = await getUserById(userId);
		if (!user) {
			ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
			return;
		}
		if (!hasPermission(roles, "user:write")({
			...res.locals,
			targetUsers: [user]
		})) {
			ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const emailLists = Array.isArray(emailList) ? emailList : [emailList];
		const emailsListObject = Object.fromEntries(emailLists.map((list) => [list, false]));
		const updatedUser = await updateUserById(user.id, { emailsList: {
			...user.emailsList,
			...emailsListObject
		} });
		logger.info(`User unsubscribed from newsletter: ${updatedUser.email}`);
		const formattedUser = mapUserToAPI(updatedUser);
		const responseData = formatResponse({
			message: t({
				en: "Successfully unsubscribed from newsletter",
				fr: "Désabonnement de la newsletter réussi",
				es: "Cancelación de suscripción al boletín exitosa"
			}),
			description: t({
				en: "You have been successfully unsubscribed from our newsletter",
				fr: "Vous avez été désabonné avec succès de notre newsletter",
				es: "Te has desuscrito exitosamente de nuestro boletín"
			}),
			data: formattedUser
		});
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Gets the newsletter subscription status for a user.
*/
const getNewsletterStatus = async (_req, res, _next) => {
	const email = res.locals.user?.email;
	const { roles } = res.locals;
	if (!email) {
		ErrorHandler.handleGenericErrorResponse(res, "USER_DATA_NOT_FOUND");
		return;
	}
	try {
		const user = await getUserByEmail(email);
		if (!user) {
			ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
			return;
		}
		if (!hasPermission(roles, "user:read")({
			...res.locals,
			targetUsers: [user]
		})) {
			ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const formattedUser = mapUserToAPI(user);
		const responseData = formatResponse({
			message: t({
				en: "Newsletter subscription status retrieved",
				fr: "Statut d'abonnement à la newsletter récupéré",
				es: "Estado de suscripción al boletín obtenido"
			}),
			data: formattedUser
		});
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};

//#endregion
export { getNewsletterStatus, subscribeToNewsletter, unsubscribeFromNewsletter };
//# sourceMappingURL=newsletter.controller.mjs.map