import { ConnectedAircraft, getPublicUser, Mission, prisma, User } from "@repo/db";
import { io } from "index";
import { sendNtfyMission } from "modules/ntfy";

export const sendAlert = async (
	id: number,
	{
		stationId,
	}: {
		stationId?: number;
	},
	user: User,
): Promise<{
	connectedAircrafts: ConnectedAircraft[];
	mission: Mission;
}> => {
	const mission = await prisma.mission.findUnique({
		where: { id: id },
	});
	const Stations = await prisma.station.findMany({
		where: {
			id: {
				in: mission?.missionStationIds,
			},
		},
	});

	if (!mission) {
		throw new Error("Mission not found");
	}

	// connectedAircrafts the alert is sent to
	const connectedAircrafts = await prisma.connectedAircraft.findMany({
		where: {
			stationId: stationId
				? stationId
				: {
						in: mission.missionStationIds,
					},
			logoutTime: null,
		},
		include: {
			Station: true,
		},
	});

	for (const aircraft of connectedAircrafts) {
		io.to(`station:${aircraft.stationId}`).emit("mission-alert", {
			...mission,
			Stations,
		});
		io.to(`desktop:${aircraft.userId}`).emit("mission-alert", {
			missionId: mission.id,
		});

		const user = await prisma.user.findUnique({
			where: { id: aircraft.userId },
		});
		if (!user) continue;
		if (user.settingsNtfyRoom) {
			await sendNtfyMission(mission, Stations, aircraft.Station, user.settingsNtfyRoom);
		}
		const existingMissionOnStationUser = await prisma.missionOnStationUsers.findFirst({
			where: {
				missionId: mission.id,
				userId: aircraft.userId,
				stationId: aircraft.stationId,
			},
		});

		if (!existingMissionOnStationUser)
			await prisma.missionOnStationUsers.create({
				data: {
					missionId: mission.id,
					userId: aircraft.userId,
					stationId: aircraft.stationId,
				},
			});
	}

	// for statistics only
	await prisma.missionsOnStations
		.createMany({
			data: mission.missionStationIds.map((stationId) => ({
				missionId: mission.id,
				stationId,
			})),
		})
		.catch((err) => {
			// Ignore if the entry already exists
		});

	await prisma.mission.update({
		where: { id: Number(id) },
		data: {
			state: "running",
			missionLog: {
				push: {
					type: "alert-log",
					auto: false,
					timeStamp: new Date().toISOString(),
					data: {
						stationId: stationId,
						user: getPublicUser(user, { ignorePrivacy: true }),
					},
				} as any,
			},
		},
	});
	return { connectedAircrafts, mission };
};
