"use client";

import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { X, CalendarIcon, Clock } from "lucide-react";
import toast from "react-hot-toast";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { getStationsAPI } from "(app)/_querys/stations";
import { createBookingAPI } from "(app)/_querys/bookings";
import { Button } from "@repo/shared-components";
import { useRouter } from "next/navigation";
import { AxiosError } from "axios";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { DateInput } from "_components/ui/DateInput";
import { Select } from "_components/ui/Select";

interface NewBookingFormData {
	type: "STATION" | "LST_01" | "LST_02" | "LST_03" | "LST_04";
	stationId?: number;
	startTime: string;
	endTime: string;
	title?: string;
	description?: string;
}

interface NewBookingModalProps {
	isOpen: boolean;
	onClose: () => void;
	onBookingCreated: () => void;
	userPermissions: string[];
}

export const NewBookingModal = ({
	isOpen,
	onClose,
	onBookingCreated,
	userPermissions,
}: NewBookingModalProps) => {
	const queryClient = useQueryClient();
	const { data: stations, isLoading: isLoadingStations } = useQuery({
		queryKey: ["stations"],
		queryFn: () => getStationsAPI({}),
	});
	const router = useRouter();
	const { mutate: createBooking, isPending: isCreateBookingLoading } = useMutation({
		mutationKey: ["createBooking"],
		mutationFn: createBookingAPI,
		onMutate() {
			// Optionally show a loading toast or indicator
			toast.loading("Buchung wird erstellt...", { id: "createBooking" });
		},
		onError(error: AxiosError) {
			const errorData = error.response?.data as { error?: string };
			toast.error(errorData?.error || "Fehler beim Erstellen der Buchung", { id: "createBooking" });
		},
		onSuccess: () => {
			toast.success("Buchung erfolgreich erstellt", { id: "createBooking" });
			queryClient.invalidateQueries({ queryKey: ["bookings"] });
			onBookingCreated();
			onClose();
			router.refresh();
		},
	});

	const newBookingSchema = z
		.object({
			type: z.enum(["STATION", "LST_01", "LST_02", "LST_03", "LST_04"], {
				message: "Bitte wähle einen Typ aus",
			}),
			stationId: z.number().optional(),
			startTime: z.string(),
			endTime: z.string(),
			title: z.string().optional(),
			description: z.string().optional(),
		})
		.superRefine((data, ctx) => {
			const start = new Date(data.startTime);
			const end = new Date(data.endTime);
			if (end <= start) {
				ctx.addIssue({
					code: z.ZodIssueCode.custom,
					message: "Endzeit muss nach der Startzeit liegen",
					path: ["endTime"],
				});
			}
		});

	const form = useForm<NewBookingFormData>({
		resolver: zodResolver(newBookingSchema),
	});
	const {
		register,
		handleSubmit,
		watch,
		setValue,
		reset,
		formState: { errors },
	} = form;
	const selectedType = watch("type");
	const hasDISPOPermission = userPermissions.includes("DISPO");

	// Reset form when modal opens
	useEffect(() => {
		if (isOpen) {
			reset();
			// Set default datetime to current hour
			const now = new Date();
			const currentHour = new Date(
				now.getFullYear(),
				now.getMonth(),
				now.getDate(),
				now.getHours(),
				0,
				0,
			);
			const nextHour = new Date(currentHour.getTime() + 60 * 60 * 1000);

			setValue("startTime", currentHour.toISOString().slice(0, 16));
			setValue("endTime", nextHour.toISOString().slice(0, 16));
		}
	}, [isOpen, reset, setValue]);

	if (!isOpen) return null;

	return (
		<div className="modal modal-open">
			<div className="modal-box max-w-2xl">
				{/* Header */}
				<div className="mb-6 flex items-center justify-between">
					<h3 className="flex items-center gap-2 text-lg font-bold">
						<CalendarIcon size={24} />
						Neue Buchung erstellen
					</h3>
					<button className="btn btn-sm btn-circle btn-ghost" onClick={onClose}>
						<X size={20} />
					</button>
				</div>

				{/* Form */}
				<form onSubmit={handleSubmit((data) => createBooking(data))} className="space-y-6">
					{/* Resource Type Selection */}
					<div className="form-control">
						<label className="label">
							<span className="label-text font-semibold">Station *</span>
						</label>
						<select {...register("type")} className="select select-bordered w-full">
							<option value="">Typ auswählen...</option>
							<option value="STATION">Station</option>
							{hasDISPOPermission && (
								<>
									<option value="LST_01">Leitstelle</option>
								</>
							)}
						</select>
						{errors.type && (
							<label className="label">
								<span className="label-text-alt text-error">{errors.type.message}</span>
							</label>
						)}
					</div>

					{/* Station Selection (only if STATION type is selected) */}
					{selectedType === "STATION" && (
						<div className="form-control">
							<label className="label">
								<span className="label-text font-semibold">Station *</span>
							</label>
							{isLoadingStations ? (
								<div className="skeleton h-12 w-full"></div>
							) : (
								<Select
									label="Station"
									name="stationId"
									form={form}
									options={stations?.map((s) => {
										return {
											value: s.id,
											label: `${s.bosCallsign} - ${s.locationState} (${s.aircraft})`,
										};
									})}
								/>
							)}
							{errors.stationId && (
								<label className="label">
									<span className="label-text-alt text-error">{errors.stationId.message}</span>
								</label>
							)}
						</div>
					)}

					{/* Time Selection */}
					<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
						<div className="form-control">
							<label className="label">
								<span className="label-text flex items-center gap-1 font-semibold">
									<Clock size={16} />
									Startzeit *
								</span>
							</label>
							<DateInput
								type="datetime-local"
								value={new Date(watch("startTime") || Date.now())}
								onChange={(date) => {
									setValue("startTime", date.toISOString());
									if (new Date(date) >= new Date(watch("endTime"))) {
										const newEndTime = new Date(new Date(date).getTime() + 60 * 60 * 3000);
										setValue("endTime", newEndTime.toISOString().slice(0, 16));
									}
								}}
								className="input input-bordered w-full"
							/>
							{errors.startTime && (
								<label className="label">
									<span className="label-text-alt text-error">{errors.startTime.message}</span>
								</label>
							)}
						</div>

						<div className="form-control">
							<label className="label">
								<span className="label-text flex items-center gap-1 font-semibold">
									<Clock size={16} />
									Endzeit *
								</span>
							</label>
							<DateInput
								type="datetime-local"
								value={new Date(watch("endTime") || Date.now())}
								onChange={(date) => {
									setValue("endTime", date.toISOString());
								}}
								className="input input-bordered w-full"
							/>
							{errors.endTime && (
								<label className="label">
									<span className="label-text-alt text-error">{errors.endTime.message}</span>
								</label>
							)}
						</div>
					</div>

					{/* Actions */}
					<div className="modal-action">
						<Button type="submit" className="btn btn-primary" isLoading={isCreateBookingLoading}>
							Buchung erstellen
						</Button>
						<button type="button" className="btn" onClick={onClose}>
							Abbrechen
						</button>
					</div>
				</form>
			</div>
		</div>
	);
};
