"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, useState } 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";

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 [loading, setLoading] = useState(false);
	const [deleteLoading, setDeleteLoading] = useState(false);
	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) => {
					setLoading(true);

					await upsertEvent(values, event?.id);
					setLoading(false);
					if (!event) redirect(`/admin/event`);
				})}
				className="grid grid-cols-6 gap-3"
			>
				<div className="card bg-base-200 shadow-xl col-span-3  max-xl:col-span-6">
					<div className="card-body">
						<h2 className="card-title">
							<FileText className="w-5 h-5" /> Allgemeines
						</h2>
						<Input form={form} label="Name" name="name" className="input-sm" />
						<MarkdownEditor form={form} name="description" />
						<Input
							form={form}
							label="Maximale Teilnehmer (Nur für live Events)"
							className="input-sm"
							{...form.register("maxParticipants", {
								valueAsNumber: true,
							})}
						/>
						<Switch form={form} name="hidden" label="Versteckt" />
						<Select
							form={form}
							name="type"
							label="Typ"
							options={Object.entries(EVENT_TYPE).map(([key, value]) => ({
								label: key,
								value: value,
							}))}
						/>
					</div>
				</div>
				<div className="card bg-base-200 shadow-xl col-span-3  max-xl:col-span-6">
					<div className="card-body">
						<h2 className="card-title">
							<Bot className="w-5 h-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"
						/>
						<Switch form={form} name="hasPresenceEvents" label="Hat Live Event" />
					</div>
				</div>
				{form.watch("hasPresenceEvents") ? (
					<div className="card bg-base-200 shadow-xl col-span-6">
						<div className="card-body">
							<div className="flex justify-between">
								<h2 className="card-title">
									<Calendar className="w-5 h-5" /> Termine
								</h2>
								{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>
								)}
							</div>

							<PaginatedTable
								ref={appointmentsTableRef}
								prismaModel={"eventAppointment"}
								filter={{
									eventId: event?.id,
								}}
								include={{
									Presenter: true,
									Participants: true,
								}}
								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="w-5 h-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 shadow-xl col-span-6">
						<div className="card-body">
							<PaginatedTable
								leftOfSearch={
									<h2 className="card-title">
										<Calendar className="w-5 h-5" /> Teilnehmer
									</h2>
								}
								searchFields={["User.firstname", "User.lastname"]}
								ref={appointmentsTableRef}
								prismaModel={"participant"}
								filter={{
									eventId: event?.id,
								}}
								include={{
									User: true,
								}}
								columns={[
									{
										header: "Vorname",
										accessorKey: "User.firstname",
									},
									{
										header: "Nachname",
										accessorKey: "User.lastname",
									},
									{
										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>
											);
										},
									},
								]}
							/>
						</div>
					</div>
				) : null}
				<div className="card bg-base-200 shadow-xl col-span-6">
					<div className="card-body ">
						<div className="flex w-full gap-4">
							<Button isLoading={loading} type="submit" className="btn btn-primary flex-1">
								Speichern
							</Button>
							{event && (
								<Button
									isLoading={deleteLoading}
									onClick={async () => {
										setDeleteLoading(true);
										await deleteEvent(event.id);
										redirect("/admin/event");
									}}
									className="btn btn-error"
								>
									Löschen
								</Button>
							)}
						</div>
					</div>
				</div>
			</form>
		</>
	);
};
