var Event = require("../models/events");
var User = require("../models/user");
const { RRule } = require("rrule");

var saveNewEvent = async (req, res) => {
	try {
		const { id, userId, title, start, end, repeated, rrule } = req.body;

		const startDate = new Date(start);
		const endDate = new Date(end);

		console.log("Parsed Start Date:", startDate);
		console.log("Parsed End Date:", endDate);

		const event = new Event({
			id,
			title,
			start: startDate,
			end: endDate,
			repeated,
			userId,
			rrule: rrule || null,
		});
		await event.save();
		res.send(event);
	} catch (error) {
		res.send(error);
	}
};

var saveNewEventArray = async (req, res) => {
	try {
		const events = req.body.events;
		if (!Array.isArray(events)) {
			return res.send({ error: "Invalid payload format" });
		}

		const savedEvents = [];

		for (const eventData of events) {
			const { id, userId, title, start, end, repeated, rrule } = eventData;

			const startDate = new Date(start);
			startDate.setMinutes(
				startDate.getMinutes() - startDate.getTimezoneOffset(),
			);
			const endDate = new Date(end);
			endDate.setMinutes(endDate.getMinutes() - endDate.getTimezoneOffset());

			console.log("Parsed Start Date:", startDate);
			console.log("Parsed End Date:", endDate);

			const event = new Event({
				id,
				title,
				start: startDate,
				end: endDate,
				repeated,
				userId,
				rrule: rrule || null,
			});
			await event.save();
			savedEvents.push(event);
		}

		res.send({ savedEvents });
	} catch (error) {
		console.error("Error při ukládání pole eventů:", error);
		res.send({ error: "Internal Server Error" });
	}
};

// Získá všechny eventy z databáze pro daného uživatele
// Projde všechny eventy a vytvoří pole individuálních event objektů, aby se odlišily opakované eventy od neopakovaných
// Pro opakované eventy se generují výskyty toho daného eventu v každém měsíci po dobu jednoho roku
// Generuje všechny výskyty (datumy) v rámci jednoho roku dle daného pravidla
// Pošle do frontendu eventy uložené eventy
var getAllEvents = async (req, res) => {
	try {
		const { userId } = req.query;
		if (!userId) {
			return res.send({ message: "Chybí parametr userId" });
		}
		const currentUser = await User.findById(userId).exec();
		if (!currentUser) {
			return res.send({ message: "Uživatel nenalezen" });
		}
		// Podle daného uživatele a jeho přiřazené skupiny posílá eventy ostatnich uživatelů do frontendu
		const usersInGroup = await User.find({ group: currentUser.group }).exec();
		const userIdsInGroup = usersInGroup.map((user) => user._id);

		const events = await Event.find({ userId: { $in: userIdsInGroup } }).exec();

		const expandedEvents = events.flatMap((event) => {
			if (event.rrule && event.start && event.end) {
				const rule = new RRule({
					...event.rrule,
					dtstart: new Date(event.start),
				});

				const startDate = new Date(event.start);
				const endDate = new Date(
					new Date().setFullYear(new Date().getFullYear() + 1),
				);

				const occurrences = rule.between(startDate, endDate, true);

				// Pro každý výskyt opakovaného datumu se nastaví start datum a end datum daného měsíce
				return occurrences.map((date) => ({
					...event.toObject(),
					start: date.toISOString(),
					end: new Date(date.getTime() + 24 * 60 * 60 * 1000).toISOString(),
				}));
			} else if (event.start && event.end) {
				// Neopakující se eventy pouze vrátí tak jak jsou
				return {
					...event.toObject(),
					start: new Date(event.start).toISOString(),
					end: new Date(event.end).toISOString(),
				};
			} else {
				console.warn(
					`Event with id ${event.id} has missing dates and was skipped.`,
				);
				return [];
			}
		});

		res.send({ events: expandedEvents });
	} catch (error) {
		console.error("Error fetching events:", error);
		res.send(error);
	}
};

var getAllEventsPure = async (req, res) => {
	try {
		const events = await Event.find().exec();

		const expandedEvents = events.flatMap((event) => {
			if (event.rrule && event.start && event.end) {
				const rule = new RRule({
					...event.rrule,
					dtstart: new Date(event.start),
				});

				const startDate = new Date(event.start);
				const endDate = new Date(
					new Date().setFullYear(new Date().getFullYear() + 1),
				);

				const occurrences = rule.between(startDate, endDate, true);

				return occurrences.map((date) => ({
					...event.toObject(),
					start: date.toISOString(),
					end: new Date(date.getTime() + 24 * 60 * 60 * 1000).toISOString(),
				}));
			} else if (event.start && event.end) {
				return {
					...event.toObject(),
					start: new Date(event.start).toISOString(),
					end: new Date(event.end).toISOString(),
				};
			} else {
				console.warn(
					`Event with id ${event.id} has missing dates and was skipped.`,
				);
				return [];
			}
		});

		res.send({ events: expandedEvents });
	} catch (error) {
		console.error("Error fetching events:", error);
		res.send(error);
	}
};

var deleteEvent = async (req, res) => {
	try {
		await Event.findOneAndDelete({ id: req.params.id });
		res.send("Event byl úspěšně smazán");
	} catch (error) {
		res.send(error);
	}
};

var changeEvent = async (req, res) => {
	try {
		const event = await Event.findOneAndUpdate(
			{ id: req.params.id },
			req.body,
			{ new: true },
		);
		res.send(event);
	} catch (error) {
		res.send(error);
	}
};

module.exports = {
	saveNewEvent,
	saveNewEventArray,
	getAllEvents,
	deleteEvent,
	changeEvent,
	getAllEventsPure,
};
