"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { BADGES, Event, EVENT_TYPE, Participant, PERMISSION, User } from "@repo/db";
import {
	EventAppointmentOptionalDefaults,
	EventAppointmentOptionalDefaultsSchema,
	EventOptionalDefaults,
	EventOptionalDefaultsSchema,
	ParticipantSchema,
} from "@repo/db/zod";
import { Bot, Calendar, FileText, UserIcon } from "lucide-react";
import { useSession } from "next-auth/react";
import { redirect } from "next/navigation";
import { useRef } from "react";
import "react-datepicker/dist/react-datepicker.css";
import { useForm } from "react-hook-form";
import { PaginatedTable, PaginatedTableRef } from "../../../../_components/PaginatedTable";
import { Button } from "../../../../_components/ui/Button";
import { Input } from "../../../../_components/ui/Input";
import { MarkdownEditor } from "../../../../_components/ui/MDEditor";
import { Select } from "../../../../_components/ui/Select";
import { Switch } from "../../../../_components/ui/Switch";
import { deleteEvent, upsertEvent } from "../action";
import { AppointmentModal } from "./AppointmentModal";
import { ParticipantModal } from "./ParticipantModal";
import { ColumnDef } from "@tanstack/react-table";
import toast from "react-hot-toast";
import Link from "next/link";

export const Form = ({ event }: { event?: Event }) => {
	const { data: session } = useSession();
	const form = useForm<EventOptionalDefaults>({
		resolver: zodResolver(EventOptionalDefaultsSchema),
		defaultValues: event
			? {
					...event,
					discordRoleId: event.discordRoleId ?? undefined,
					maxParticipants: event.maxParticipants ?? undefined,
					finisherMoodleCourseId: event.finisherMoodleCourseId ?? undefined,
				}
			: undefined,
	});
	const appointmentForm = useForm<EventAppointmentOptionalDefaults>({
		resolver: zodResolver(EventAppointmentOptionalDefaultsSchema),
		defaultValues: {
			eventId: event?.id,
			presenterId: session?.user?.id,
		},
	});
	const participantForm = useForm<Participant>({
		resolver: zodResolver(ParticipantSchema),
	});
	const appointmentsTableRef = useRef<PaginatedTableRef>(null);
	const appointmentModal = useRef<HTMLDialogElement>(null);
	const participantModal = useRef<HTMLDialogElement>(null);

	return (
		<>
			<AppointmentModal
				participantModal={participantModal}
				participantForm={participantForm}
				appointmentForm={appointmentForm}
				ref={appointmentModal}
				appointmentsTableRef={appointmentsTableRef}
				event={event}
			/>
			<ParticipantModal participantForm={participantForm} ref={participantModal} />
			<form
				onSubmit={form.handleSubmit(async (values) => {
					await upsertEvent(values, event?.id);
					toast.success("Event erfolgreich gespeichert");
					if (!event) redirect(`/admin/event`);
				})}
				className="grid grid-cols-6 gap-3"
			>
				<div className="card bg-base-200 col-span-3 shadow-xl max-xl:col-span-6">
					<div className="card-body">
						<h2 className="card-title">
							<FileText className="h-5 w-5" /> Allgemeines
						</h2>
						<Select
							form={form}
							name="type"
							label="Typ"
							options={Object.entries(EVENT_TYPE).map(([key, value]) => ({
								label: key,
								value: value,
							}))}
						/>
						<Input form={form} label="Name" name="name" className="input-sm" />
						<MarkdownEditor form={form} name="description" />
						<MarkdownEditor form={form} name="descriptionShort" />
					</div>
				</div>
				<div className="card bg-base-200 col-span-3 shadow-xl max-xl:col-span-6">
					<div className="card-body">
						<h2 className="card-title">
							<Bot className="h-5 w-5" /> Automation
						</h2>
						<Input
							name="finisherMoodleCourseId"
							form={form}
							label="Moodle Abschluss Kurs ID"
							className="input-sm"
						/>
						<Select
							isMulti
							form={form}
							name="finishedBadges"
							label="Badges bei Abschluss"
							options={Object.entries(BADGES).map(([key, value]) => ({
								label: value,
								value: key,
							}))}
						/>
						<Select
							isMulti
							form={form}
							name="requiredBadges"
							label="Benötigte Badges"
							options={Object.entries(BADGES).map(([key, value]) => ({
								label: value,
								value: key,
							}))}
						/>
						<Select
							isMulti
							form={form}
							name="finishedPermissions"
							label="Berechtigungen bei Abschluss"
							options={Object.entries(PERMISSION).map(([key, value]) => ({
								label: value,
								value: key,
							}))}
						/>
						<Input
							name="discordRoleId"
							form={form}
							label="Discord Rolle für eingeschriebene Teilnehmer"
							className="input-sm"
						/>
						<Input
							form={form}
							label="Maximale Teilnehmer (Nur für live Events)"
							className="input-sm"
							{...form.register("maxParticipants", {
								valueAsNumber: true,
							})}
						/>
						<Switch form={form} name="hasPresenceEvents" label="Hat Live Event" />
						<div className="divider w-full" />

						<Switch form={form} name="hidden" label="Event verstecken" />
					</div>
				</div>
				{form.watch("hasPresenceEvents") ? (
					<div className="card bg-base-200 col-span-6 shadow-xl">
						<div className="card-body">
							<PaginatedTable
								ref={appointmentsTableRef}
								prismaModel={"eventAppointment"}
								filter={{
									eventId: event?.id,
								}}
								include={{
									Presenter: true,
									Participants: true,
								}}
								leftOfSearch={
									<h2 className="card-title">
										<Calendar className="h-5 w-5" /> Termine
									</h2>
								}
								rightOfSearch={
									event && (
										<button
											className="btn btn-primary btn-outline"
											onClick={() => {
												appointmentModal.current?.showModal();
												appointmentForm.reset({
													id: undefined,
													eventId: event.id,
													presenterId: session?.user?.id,
												});
											}}
										>
											Hinzufügen
										</button>
									)
								}
								columns={
									[
										{
											header: "Datum",
											accessorKey: "appointmentDate",
											accessorFn: (date) => new Date(date.appointmentDate).toLocaleString(),
										},
										{
											header: "Presenter",
											accessorKey: "presenter",
											cell: ({ row }) => (
												<div className="flex items-center">
													<span className="ml-2">
														{row.original.Presenter.firstname} {row.original.Presenter.lastname}
													</span>
												</div>
											),
										},
										{
											header: "Teilnehmer",
											accessorKey: "Participants",
											cell: ({ row }) => (
												<div className="flex items-center">
													<UserIcon className="h-5 w-5" />
													<span className="ml-2">{row.original.Participants.length}</span>
												</div>
											),
										},
										{
											header: "Aktionen",
											cell: ({ row }) => {
												return (
													<div className="flex gap-2">
														<button
															onSubmit={() => false}
															type="button"
															onClick={() => {
																appointmentForm.reset(row.original);
																appointmentModal.current?.showModal();
															}}
															className="btn btn-sm btn-outline"
														>
															Bearbeiten
														</button>
													</div>
												);
											},
										},
									] as ColumnDef<
										EventAppointmentOptionalDefaults & {
											Presenter: User;
											Participants: Participant[];
										}
									>[]
								}
							/>
						</div>
					</div>
				) : null}
				{!form.watch("hasPresenceEvents") ? (
					<div className="card bg-base-200 col-span-6 shadow-xl">
						<div className="card-body">
							<PaginatedTable
								leftOfSearch={
									<h2 className="card-title">
										<UserIcon className="h-5 w-5" /> Teilnehmer
									</h2>
								}
								searchFields={["User.firstname", "User.lastname", "User.publicId"]}
								ref={appointmentsTableRef}
								prismaModel={"participant"}
								filter={{
									eventId: event?.id,
								}}
								include={{
									User: true,
								}}
								columns={
									[
										{
											header: "Vorname",
											accessorKey: "User.firstname",
											cell: ({ row }) => {
												return (
													<Link
														className="hover:underline"
														href={`/admin/user/${row.original.User.id}`}
													>
														{row.original.User.firstname}
													</Link>
												);
											},
										},
										{
											header: "Nachname",
											accessorKey: "User.lastname",
											cell: ({ row }) => {
												return (
													<Link
														className="hover:underline"
														href={`/admin/user/${row.original.User.id}`}
													>
														{row.original.User.lastname}
													</Link>
												);
											},
										},
										{
											header: "VAR-Nummer",
											accessorKey: "User.publicId",
											cell: ({ row }) => {
												return (
													<Link
														className="hover:underline"
														href={`/admin/user/${row.original.User.id}`}
													>
														{row.original.User.publicId}
													</Link>
												);
											},
										},
										{
											header: "Moodle Kurs abgeschlossen",
											accessorKey: "finisherMoodleCurseCompleted",
										},
										{
											header: "Aktionen",
											cell: ({ row }) => {
												return (
													<div className="flex gap-2">
														<button
															onSubmit={() => false}
															type="button"
															onClick={() => {
																participantForm.reset(row.original);
																participantModal.current?.showModal();
															}}
															className="btn btn-sm btn-outline"
														>
															Bearbeiten
														</button>
													</div>
												);
											},
										},
									] as ColumnDef<Participant & { User: User }>[]
								}
							/>
						</div>
					</div>
				) : null}
				<div className="card bg-base-200 col-span-6 shadow-xl">
					<div className="card-body">
						<div className="flex w-full gap-4">
							<Button
								isLoading={form.formState.isSubmitting}
								type="submit"
								className="btn btn-primary flex-1"
							>
								Speichern
							</Button>
							{event && (
								<Button
									onClick={async () => {
										await deleteEvent(event.id);
										redirect("/admin/event");
									}}
									className="btn btn-error"
								>
									Löschen
								</Button>
							)}
						</div>
					</div>
				</div>
			</form>
		</>
	);
};
