"use client";
import { useEffect } from "react";
import { CheckCircledIcon, CalendarIcon, EnterIcon } from "@radix-ui/react-icons";
import { Event, EventAppointment, Participant, User } from "@repo/db";
import { cn } from "../../../../helper/cn";
import { inscribeToMoodleCourse, upsertParticipant } from "../actions";
import { Check, Clock10Icon, EyeIcon, TriangleAlert } from "lucide-react";
import { useForm } from "react-hook-form";
import { ParticipantOptionalDefaults, ParticipantOptionalDefaultsSchema } from "@repo/db/zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Select } from "../../../_components/ui/Select";
import toast from "react-hot-toast";
import { useRouter } from "next/navigation";
import { eventCompleted } from "../../../../helper/events";

interface ModalBtnProps {
	title: string;
	event: Event;
	dates: EventAppointment[];
	selectedAppointments: EventAppointment[];
	participant?: Participant;
	user: User;
	modalId: string;
}

const ModalBtn = ({
	title,
	dates,
	modalId,
	participant,
	selectedAppointments,
	event,
	user,
}: ModalBtnProps) => {
	useEffect(() => {
		const modal = document.getElementById(modalId) as HTMLDialogElement;
		const handleOpen = () => {
			document.body.classList.add("modal-open");
		};
		const handleClose = () => {
			document.body.classList.remove("modal-open");
		};
		modal?.addEventListener("show", handleOpen);
		modal?.addEventListener("close", handleClose);
		return () => {
			modal?.removeEventListener("show", handleOpen);
			modal?.removeEventListener("close", handleClose);
		};
	}, [modalId]);
	const router = useRouter();

	const canSelectDate =
		event.hasPresenceEvents &&
		!participant?.attended &&
		(selectedAppointments.length === 0 || participant?.appointmentCancelled);

	const openModal = () => {
		const modal = document.getElementById(modalId) as HTMLDialogElement;
		document.body.classList.add("modal-open");
		modal?.showModal();
	};

	const closeModal = () => {
		const modal = document.getElementById(modalId) as HTMLDialogElement;
		document.body.classList.remove("modal-open");
		modal?.close();
	};
	const selectAppointmentForm = useForm<ParticipantOptionalDefaults>({
		resolver: zodResolver(ParticipantOptionalDefaultsSchema),
		defaultValues: {
			eventId: event.id,
			userId: user.id,
			...participant,
		},
	});
	const selectedAppointment = selectedAppointments[0];
	const selectedDate = dates.find(
		(date) =>
			date.id === selectAppointmentForm.watch("eventAppointmentId") || selectedAppointment?.id,
	);
	const ownIndexInParticipantList = (selectedDate as any)?.Participants?.findIndex(
		(p: Participant) => p.userId === user.id,
	);

	const ownPlaceInParticipantList =
		ownIndexInParticipantList === -1
			? (selectedDate as any)?.Participants?.length + 1
			: ownIndexInParticipantList + 1;

	return (
		<>
			<button
				className={cn(
					"btn btn-outline btn-info btn-wide",
					event.type === "OBLIGATED_COURSE" && "btn-secondary",
					eventCompleted(event, participant) && "btn-success",
				)}
				onClick={openModal}
			>
				{participant && !eventCompleted(event, participant) && (
					<>
						<EyeIcon /> Anzeigen
					</>
				)}
				{!participant && (
					<>
						<EnterIcon /> Anmelden
					</>
				)}
				{eventCompleted(event, participant) && (
					<>
						<Check /> Abgeschlossen
					</>
				)}
			</button>
			<dialog id={modalId} className="modal">
				<div className="modal-box">
					<h3 className="font-bold text-lg">{title}</h3>
					{event.hasPresenceEvents && (
						<div>
							{canSelectDate && (
								<div className="flex items-center gap-2 justify-center">
									<CalendarIcon />
									{!!dates.length && (
										// TODO: Prevent users from selecting an appointment that is full
										<Select
											form={selectAppointmentForm as any}
											options={dates.map((date) => ({
												label: `${new Date(
													date.appointmentDate,
												).toLocaleString()} - (${(date as any)._count.Participants}/${event.maxParticipants})`,
												value: date.id,
											}))}
											name="eventAppointmentId"
											label={""}
											className="min-w-[200px]"
										/>
									)}
									{}
									{!dates.length && (
										<p className="text-center text-info">Keine Termine verfügbar</p>
									)}
								</div>
							)}
							{!canSelectDate && participant?.attended && (
								<p className="py-4 flex items-center gap-2 justify-center">
									<CheckCircledIcon className="text-success" />
									Du hast an dem Presenztermin teilgenommen
								</p>
							)}
							{!!selectedDate &&
								!!event.maxParticipants &&
								!!ownPlaceInParticipantList &&
								!!(ownPlaceInParticipantList > event.maxParticipants) && (
									<p
										role="alert"
										className="py-4 my-5 flex items-center gap-2 justify-center border alert alert-error alert-outline"
									>
										<TriangleAlert className="h-6 w-6 shrink-0 stroke-current" fill="none" />
										Dieser Termin ist ausgebucht, wahrscheinlich wirst du nicht teilnehmen können.
										(Listenplatz: {ownPlaceInParticipantList} , max. {event.maxParticipants})
									</p>
								)}
							{selectedAppointment && !participant?.appointmentCancelled && (
								<>
									<div className="flex items-center gap-2 justify-center">
										<p>Dein Ausgewähler Termin</p>

										<p>{new Date(selectedAppointment.appointmentDate).toLocaleString()}</p>
										<button
											onClick={async () => {
												await upsertParticipant({
													eventId: event.id,
													userId: participant!.userId,
													appointmentCancelled: true,
													statusLog: [
														...(participant?.statusLog as any),
														{
															data: {
																appointmentId: selectedAppointment.id,
																appointmentDate: selectedAppointment.appointmentDate,
															},
															user: `${user?.firstname} ${user?.lastname} - ${user?.publicId}`,
															event: "Termin abgesagt",
															timestamp: new Date(),
														},
													],
												});
												toast.success("Termin abgesagt");
												router.refresh();
											}}
											className="btn btn-error btn-outline btn-sm"
										>
											absagen
										</button>
									</div>

									<p className="mt-3 text-center">
										Bitte finde dich an diesem Termin in unserem Discord ein.
									</p>
								</>
							)}
						</div>
					)}
					{event.finisherMoodleCourseId && (
						<MoodleCourseIndicator
							participant={participant}
							user={user}
							moodleCourseId={event.finisherMoodleCourseId}
							completed={participant?.finisherMoodleCurseCompleted || false}
							event={event}
						/>
					)}
					<div className="modal-action flex justify-between">
						<button className="btn" onClick={closeModal}>
							Abbrechen
						</button>
						{!!canSelectDate && (
							<button
								className={cn(
									"btn btn-info btn-outline btn-wide",
									event.type === "OBLIGATED_COURSE" && "btn-secondary",
								)}
								onClick={async () => {
									const data = selectAppointmentForm.getValues();
									if (!data.eventAppointmentId) return;

									await upsertParticipant({
										...data,
										enscriptionDate: new Date(),
										statusLog: data.statusLog?.filter((log) => log !== null),
										appointmentCancelled: false,
									});
									router.refresh();
									closeModal();
								}}
							>
								<EnterIcon /> Anmelden
							</button>
						)}
					</div>
				</div>
				<button className="modal-backdrop" onClick={closeModal}>
					Abbrechen
				</button>
			</dialog>
		</>
	);
};

export default ModalBtn;

const MoodleCourseIndicator = ({
	completed,
	moodleCourseId,
	event,
	participant,
	user,
}: {
	user: User;
	participant?: Participant;
	completed?: boolean;
	moodleCourseId: string;
	event: Event;
}) => {
	const courseUrl = `${process.env.NEXT_PUBLIC_MOODLE_URL}/course/view.php?id=${moodleCourseId}`;
	if (event.hasPresenceEvents && !participant?.attended)
		return (
			<p className="py-4 flex items-center gap-2 justify-center">
				<Clock10Icon className="text-error" />
				Abschlusstest erst nach Teilnahme verfügbar
			</p>
		);
	if (completed)
		return (
			<p className="py-4 flex items-center gap-2 justify-center">
				<CheckCircledIcon className="text-success" />
				Moodle Kurs abgeschlossen
			</p>
		);
	return (
		<p className="py-4 flex items-center gap-2 justify-center">
			Moodle-Kurs Benötigt
			<button
				className="btn btn-xs btn-info ml-2"
				onClick={async () => {
					await upsertParticipant({
						eventId: event.id,
						userId: user.id,
						finisherMoodleCurseCompleted: false,
					});

					if (user.moodleId) {
						await inscribeToMoodleCourse(moodleCourseId, user.moodleId);
					}
					window.open(courseUrl, "_blank");
				}}
			>
				Zum Moodle Kurs
			</button>
		</p>
	);
};
