"use client";
import { useSession } from "next-auth/react";
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
import { useEffect, useRef, useState } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { getStationsAPI } from "_querys/stations";
import { editConnectedAircraftAPI, getConnectedAircraftsAPI } from "_querys/aircrafts";
import { Prisma } from "@repo/db";
import { Button, cn, getNextDateWithTime } from "@repo/shared-components";
import { Select } from "_components/Select";
import { Calendar, Radio } from "lucide-react";
import { getBookingsAPI } from "_querys/bookings";

export const ConnectionBtn = () => {
	const modalRef = useRef<HTMLDialogElement>(null);
	const connection = usePilotConnectionStore((state) => state);
	const [form, setForm] = useState<{
		logoffTime: string | null;
		selectedStationId: number | null;
		debugPosition: boolean;
	}>({
		logoffTime: null,
		selectedStationId: null,
		debugPosition: false,
	});

	const { data: stations } = useQuery({
		queryKey: ["stations"],
		queryFn: () => getStationsAPI(),
	});
	const { data: bookings } = useQuery({
		queryKey: ["bookings"],
		queryFn: () =>
			getBookingsAPI({
				startTime: {
					lte: new Date(Date.now() + 8 * 60 * 60 * 1000),
				},
				endTime: {
					gte: new Date(),
				},
			}),
	});

	const aircraftMutation = useMutation({
		mutationFn: ({
			change,
			sessionId,
		}: {
			sessionId: number;
			change: Prisma.ConnectedAircraftUpdateInput;
		}) => editConnectedAircraftAPI(sessionId, change),
	});

	useEffect(() => {
		if (stations && stations.length > 0 && form.selectedStationId === null) {
			setForm((prevForm) => ({
				...prevForm,
				selectedStationId: stations[0]?.id ?? null,
			}));
		}
	}, [stations, form.selectedStationId]);

	useEffect(() => {
		// Disconnect the socket when the component unmounts
		return () => {
			connection.disconnect();
		};
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [connection.disconnect]);

	const { data: connectedAircrafts } = useQuery({
		queryKey: ["aircrafts"],
		queryFn: () => getConnectedAircraftsAPI(),
	});

	const session = useSession();
	const uid = session.data?.user?.id;
	if (!uid) return null;
	console.log(bookings);
	return (
		<div className="rounded-box bg-base-200 flex items-center justify-center gap-2 p-1">
			{connection.message.length > 0 && (
				<span className="text-error mx-2">{connection.message}</span>
			)}

			{connection.status == "connected" ? (
				<button
					className="btn btn-sm btn-soft btn-success"
					type="submit"
					onSubmit={() => false}
					onClick={() => {
						modalRef.current?.showModal();
					}}
				>
					Verbunden
				</button>
			) : (
				<button
					type="submit"
					onSubmit={() => false}
					onClick={() => {
						modalRef.current?.showModal();
					}}
					className="btn btn-sm btn-soft btn-info"
				>
					{connection.status == "disconnected" ? "Verbinden" : connection.status}
				</button>
			)}

			<dialog ref={modalRef} className="modal">
				<div className="modal-box flex flex-col items-center justify-center">
					{connection.status == "connected" ? (
						<h3 className="mb-5 text-lg font-bold">
							Verbunden als{" "}
							<span className="text-info">&lt;{connection.selectedStation?.bosCallsign}&gt;</span>
						</h3>
					) : (
						<h3 className="mb-5 text-lg font-bold">Als Pilot anmelden</h3>
					)}
					{connection.status !== "connected" && (
						<div className="w-full">
							<Select
								placeholder="Wähle eine Station"
								onChange={(v) =>
									setForm({
										...form,
										selectedStationId: parseInt(v),
									})
								}
								value={form.selectedStationId ?? ""}
								formatOptionLabel={(option: unknown) =>
									(option as { component: React.ReactNode }).component
								}
								options={
									stations?.map((station) => {
										const booking = bookings?.find((b) => b.stationId == station.id);
										return {
											value: station.id.toString(),
											label: station.bosCallsign,
											component: (
												<div>
													<span className="flex items-center gap-2">
														{connectedAircrafts?.find((a) => a.stationId == station.id) && (
															<Radio className="text-warning" size={15} />
														)}
														{booking && (
															<div
																className="tooltip tooltip-right"
																data-tip={`${new Date(booking.startTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} - ${new Date(booking.endTime).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} Uhr gebucht von ${booking.userId == session.data?.user?.id ? "dir" : booking.User.fullName}`}
															>
																<Calendar
																	className={
																		cn(
																			"text-warning",
																			booking?.userId === session.data?.user?.id,
																		) && "text-success"
																	}
																	size={15}
																/>
															</div>
														)}
														{station.bosCallsign}
													</span>
												</div>
											),
										};
									}) ?? []
								}
							/>
						</div>
					)}
					<fieldset className="fieldset mt-4 w-full">
						<label className="floating-label w-full text-base">
							<span>Logoff Zeit (LCL)</span>
							<input
								onChange={(e) => {
									const value = e.target.value;
									setForm({
										...form,
										logoffTime: value,
									});
								}}
								value={form.logoffTime ?? ""}
								type="time"
								className="input w-full"
							/>
						</label>
						{connection.status == "disconnected" && (
							<p className="fieldset-label">Du kannst diese Zeit später noch anpassen.</p>
						)}
					</fieldset>

					{session.data?.user.permissions.includes("ADMIN_STATION") &&
						connection.status === "disconnected" && (
							<fieldset className="fieldset bg-base-100 border-base-300 rounded-box w-full border p-4">
								<legend className="fieldset-legend">Debug-optionen</legend>
								<label className="label">
									<input
										checked={form.debugPosition}
										onChange={(e) => setForm({ ...form, debugPosition: e.target.checked })}
										type="checkbox"
										className="checkbox"
									/>
									Zufalls Position für 2h anzeigen
								</label>
							</fieldset>
						)}
					<div className="modal-action flex w-full justify-between">
						<form method="dialog" className="flex w-full justify-between">
							<button className="btn btn-soft">Zurück</button>
							{connection.status == "connected" ? (
								<>
									<Button
										className="btn"
										onClick={async () => {
											if (!connection.connectedAircraft) return;
											const [logoffHours, logoffMinutes] =
												form.logoffTime?.split(":").map(Number) || [];

											await aircraftMutation.mutateAsync({
												sessionId: connection.connectedAircraft.id,
												change: {
													esimatedLogoutTime:
														logoffHours !== undefined && logoffMinutes !== undefined
															? getNextDateWithTime(logoffHours, logoffMinutes)
															: null,
												},
											});
											modalRef.current?.close();
										}}
									>
										Logoff-Zeit speichern
									</Button>
									<button
										className="btn btn-soft btn-error"
										type="submit"
										onSubmit={() => false}
										onClick={() => {
											connection.disconnect();
											modalRef.current?.close();
										}}
									>
										Verbindung Trennen
									</button>
								</>
							) : (
								<Button
									type="submit"
									onSubmit={() => false}
									onClick={async () => {
										const selectedStation = stations?.find(
											(station) =>
												station.id === parseInt(form.selectedStationId?.toString() || ""),
										);
										if (selectedStation) {
											const [logoffHours, logoffMinutes] =
												form.logoffTime?.split(":").map(Number) || [];

											await connection.connect(
												uid,
												form.selectedStationId?.toString() || "",
												form.logoffTime && logoffHours !== undefined && logoffMinutes !== undefined
													? getNextDateWithTime(logoffHours, logoffMinutes).toISOString()
													: "",
												selectedStation,
												session.data!.user,
												form.debugPosition,
											);
										}
										modalRef.current?.close();
									}}
									className="btn btn-soft btn-info"
								>
									{connection.status == "disconnected" ? "Verbinden" : connection.status}
								</Button>
							)}
						</form>
					</div>
				</div>
			</dialog>
		</div>
	);
};

export const Connection = () => {
	return (
		<div>
			<ConnectionBtn />
		</div>
	);
};
