"use client";
import React, { useEffect, useState } from "react";
import { FMS_STATUS_TEXT_COLORS } from "_helpers/fmsStatusColors";
import { toast } from "react-hot-toast";
import {
	Ban,
	BellRing,
	Flag,
	Hash,
	ListCollapse,
	LocateFixed,
	MapPin,
	Navigation,
	Plus,
	Repeat2,
	Trash,
	User,
	SmartphoneNfc,
	CheckCheck,
	Cross,
} from "lucide-react";
import {
	getPublicUser,
	HpgState,
	HpgValidationState,
	Mission,
	MissionAlertLog,
	MissionCompletedLog,
	MissionLog,
	MissionMessageLog,
	Prisma,
	Station,
} from "@repo/db";
import { usePannelStore } from "_store/pannelStore";
import { useSession } from "next-auth/react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { deleteMissionAPI, editMissionAPI, sendMissionAPI } from "_querys/missions";
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
import { getStationsAPI } from "_querys/stations";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
import { getOsmAddress } from "_querys/osm";
import { hpgStateToFMSStatus } from "_helpers/hpgStateToFmsStatus";

const Einsatzdetails = ({
	mission,
	hpgNeedsAttention,
}: {
	mission: Mission;
	hpgNeedsAttention?: boolean;
}) => {
	const session = useSession();
	const queryClient = useQueryClient();
	const deleteMissionMutation = useMutation({
		mutationKey: ["missions"],
		mutationFn: deleteMissionAPI,
		onSuccess: () => {
			queryClient.invalidateQueries({
				queryKey: ["missions"],
			});
		},
	});
	const { data: aircrafts } = useQuery({
		queryKey: ["aircrafts"],
		queryFn: getConnectedAircraftsAPI,
	});
	const sendAlertMutation = useMutation({
		mutationKey: ["missions"],
		mutationFn: (id: number) => sendMissionAPI(id, {}),
		onError: (error) => {
			console.error(error);
			toast.error("Fehler beim Alarmieren");
		},
		onSuccess: (data) => {
			toast.success(data.message);
			queryClient.invalidateQueries({
				queryKey: ["missions"],
			});
		},
	});
	const editMissionMutation = useMutation({
		mutationKey: ["missions"],
		mutationFn: ({ id, mission }: { id: number; mission: Prisma.MissionUpdateInput }) =>
			editMissionAPI(id, mission),
		onSuccess: () => {
			toast.success("Gespeichert");
			queryClient.invalidateQueries({
				queryKey: ["missions"],
			});
		},
	});

	const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";
	const { setMissionFormValues, setOpen, setEditingMission } = usePannelStore((state) => state);
	const [ignoreHpg, setIgnoreHpg] = useState(false);
	return (
		<div className="p-4 text-base-content">
			<div className="flex items-center justify-between mb-3">
				<h2 className="flex items-center gap-2 text-lg font-bold">
					<Flag /> Einsatzdetails
				</h2>
				{mission.state !== "draft" && dispatcherConnected && (
					<div className="space-x-2">
						<div
							className="tooltip tooltip-primary tooltip-left font-semibold"
							data-tip="Einsatzdaten übernehmen"
						>
							<button
								className="btn btn-xs btn-primary btn-dash flex items-center gap-2"
								onClick={() => {
									setMissionFormValues({
										...mission,
										id: undefined,
										hpgAmbulanceState: null,
										hpgFireEngineState: null,
										hpgPoliceState: null,
										hpgLocationLat: undefined,
										hpgLocationLng: undefined,
										state: "draft",
										addressAdditionalInfo: mission.addressAdditionalInfo || undefined,
										addressMissionLocation: mission.addressAdditionalInfo || undefined,
									});
									setOpen(true);
								}}
							>
								<Repeat2 size={16} />
							</button>
						</div>
						<div
							className="tooltip tooltip-warning tooltip-left font-semibold z-[9999]"
							data-tip="Einsatz abschließen"
						>
							<button
								className="btn btn-xs btn-warning flex items-center gap-2"
								onClick={() => {
									if (!session.data) return;
									editMissionMutation.mutate({
										id: mission.id,
										mission: {
											state: "finished",
											missionLog: {
												push: {
													type: "completed-log",
													auto: false,
													timeStamp: new Date().toISOString(),
													data: {
														user: getPublicUser(session.data?.user, { ignorePrivacy: true }),
													},
												} as any,
											},
										},
									});
								}}
							>
								<CheckCheck size={16} />
							</button>
						</div>
					</div>
				)}
			</div>
			<ul className="text-base-content font-semibold">
				<li className="flex items-center gap-2 mb-1">
					<BellRing size={16} /> {mission.missionKeywordCategory}
				</li>
				<li className="flex items-center gap-2 mb-1">
					<ListCollapse size={16} />
					{mission.missionKeywordName}
				</li>
				<li className="flex items-center gap-2 mt-3">
					<Hash size={16} />
					{mission.publicId}
				</li>
			</ul>
			<div className="divider mt-0 mb-0" />
			<div className="text-sm font-semibold">
				<p className="flex items-center gap-2">
					<MapPin size={16} /> {mission.addressLat} {mission.addressLng}
				</p>
				<p className="flex items-center gap-2">
					<Navigation size={16} /> {mission.addressStreet}
				</p>
				<p className="flex items-center gap-2">
					<LocateFixed size={16} />
					{mission.addressZip && mission.addressCity ? (
						`${mission.addressZip} ${mission.addressCity}`
					) : (
						<span className="italic text-gray-400">PLZ / Ort nicht angegeben</span>
					)}
				</p>
			</div>
			{mission.state === "draft" && (
				<div>
					<div className="divider mt-0 mb-0" />

					{hpgNeedsAttention && (
						<div className="form-control mb-2">
							<label className="flex items-center gap-2 cursor-pointer">
								<input
									type="checkbox"
									className="checkbox checkbox-sm checkbox-primary"
									checked={ignoreHpg}
									onChange={(e) => setIgnoreHpg(e.target.checked)}
								/>
								<span className="label-text font-semibold leading-6">
									Ohne HPG-Mission alarmieren
								</span>
							</label>
						</div>
					)}

					<div className="flex items-center gap-2 w-full">
						{(!hpgNeedsAttention || ignoreHpg) &&
							mission.hpgValidationState !== HpgValidationState.POSITION_AMANDED && (
								<button
									className="btn btn-sm btn-info btn-outline flex-3"
									onClick={() => {
										setOpen(false);
										setMissionFormValues({});
										setEditingMission(false, null);
										sendAlertMutation.mutate(mission.id);
									}}
								>
									<span className="flex items-center gap-2">
										<BellRing size={16} /> Alarmieren
									</span>
								</button>
							)}
						{!ignoreHpg &&
							hpgNeedsAttention &&
							mission.hpgValidationState !== HpgValidationState.POSITION_AMANDED && (
								<button
									className="btn btn-sm btn-info btn-outline flex-3"
									onClick={() => {
										setOpen(false);
										setMissionFormValues({});
										setEditingMission(false, null);
										sendAlertMutation.mutate(mission.id);
									}}
									disabled
								>
									<span className="flex items-center gap-2">
										{mission.hpgValidationState === HpgValidationState.PENDING && (
											<div>
												<span className="loading loading-spinner loading-md"></span> HPG-Validierung
												läuft...
											</div>
										)}
										{mission.hpgValidationState === HpgValidationState.HPG_BUSY &&
											"HPG-Client busy"}
										{mission.hpgValidationState === HpgValidationState.HPG_DISCONNECT &&
											"HPG-Client nicht verbunden"}
										{mission.hpgValidationState === HpgValidationState.INVALID &&
											"HPG-Client fehlerhaft"}
										{mission.hpgValidationState === HpgValidationState.HPG_INVALID_MISSION &&
											"Fehlerhafte HPG-Mission"}
										{mission.hpgValidationState === HpgValidationState.NOT_VALIDATED &&
											"HPG-Validierung nicht angestoßen"}
									</span>
								</button>
							)}

						{!ignoreHpg && mission.hpgValidationState === HpgValidationState.POSITION_AMANDED && (
							<button
								className="btn btn-sm btn-warning btn-outline flex-3"
								onClick={async () => {
									const { parsed } = await getOsmAddress(
										mission.hpgLocationLat || mission.addressLat,
										mission.hpgLocationLng || mission.addressLng,
									);
									await editMissionMutation.mutateAsync({
										id: mission.id,
										mission: {
											addressLat: mission.hpgLocationLat || mission.addressLat,
											addressLng: mission.hpgLocationLng || mission.addressLng,
											addressStreet: parsed.addressStreet,
											addressCity: parsed.addressCity,
											addressZip: parsed.addressZip,
										},
									});

									setOpen(false);
									setMissionFormValues({});
									setEditingMission(false, null);
									await sendAlertMutation.mutateAsync(mission.id);
								}}
							>
								<span className="flex items-center gap-2">
									<BellRing size={16} /> Mit neuer Position alarmieren
								</span>
							</button>
						)}

						<button
							className="btn btn-sm btn-primary btn-dash flex items-center gap-2"
							onClick={() => {
								setMissionFormValues({
									...mission,
									id: undefined,
									hpgAmbulanceState: null,
									hpgFireEngineState: null,
									hpgPoliceState: null,
									hpgLocationLat: undefined,
									hpgLocationLng: undefined,
									state: "draft",
									addressAdditionalInfo: mission.addressAdditionalInfo || undefined,
									addressMissionLocation: mission.addressAdditionalInfo || undefined,
								});
								setOpen(true);
							}}
						>
							<Repeat2 size={18} /> Daten übernehmen
						</button>
						<button
							className="btn btn-sm btn-error btn-outline"
							onClick={() => {
								deleteMissionMutation.mutate(mission.id);
							}}
						>
							<Trash size={18} />
						</button>
					</div>
				</div>
			)}
		</div>
	);
};

const Patientdetails = ({ mission }: { mission: Mission }) => {
	return (
		<div className="p-4 text-base-content">
			<h2 className="flex items-center gap-2 text-lg font-bold mb-3">
				<User /> Patientendetails
			</h2>
			<p className="text-base-content font-semibold">{mission.missionPatientInfo}</p>
			<div className="divider my-2" />
			<h2 className="flex items-center gap-2 text-lg font-bold mb-3">
				<Cross /> Einsatzinformationen
			</h2>
			<p className="text-base-content font-semibold">{mission.missionAdditionalInfo}</p>
		</div>
	);
};

const Rettungsmittel = ({ mission }: { mission: Mission }) => {
	const queryClient = useQueryClient();
	const [selectedStation, setSelectedStation] = useState<
		Station | "ambulance" | "police" | "firebrigade" | null
	>(null);
	const { data: conenctedAircrafts } = useQuery({
		queryKey: ["aircrafts"],
		queryFn: getConnectedAircraftsAPI,
	});
	const updateMissionMutation = useMutation({
		mutationKey: ["missions", "stations-mission", mission.id],
		mutationFn: ({ id, missionEdit }: { id: number; missionEdit: Prisma.MissionUpdateInput }) =>
			editMissionAPI(id, missionEdit),

		onError: (error) => {
			console.error(error);
			toast.error("Fehler beim Speichern");
		},
		onSuccess: () => {
			// Cache invalidieren → Query wird neu ausgeführt
			queryClient.invalidateQueries({
				queryKey: ["missions"],
			});
		},
	});

	const { data: missionStations, refetch: refetchMissionStationIds } = useQuery({
		queryKey: ["stations-mission", mission.id],
		queryFn: () =>
			getStationsAPI({
				id: {
					in: mission.missionStationIds,
				},
			}),
	});
	useEffect(() => {
		refetchMissionStationIds();
	}, [mission.missionStationIds, refetchMissionStationIds]);

	const { data: allStations } = useQuery({
		queryKey: ["stations"],
		queryFn: () => getStationsAPI(),
	});

	useEffect(() => {
		if (allStations) {
			const stationsNotItMission = allStations.filter(
				(s) => !mission.missionStationIds.includes(s.id),
			);
			if (stationsNotItMission[0]) {
				setSelectedStation(stationsNotItMission[0]);
			}
		}
	}, [allStations, mission.missionStationIds]);

	const sendAlertMutation = useMutation({
		mutationKey: ["missions"],
		mutationFn: ({
			id,
			stationId,
			vehicleName,
		}: {
			id: number;
			stationId?: number;
			vehicleName?: "ambulance" | "police" | "firebrigade";
		}) => sendMissionAPI(id, { stationId, vehicleName }),
		onError: (error) => {
			console.error(error);
			toast.error("Fehler beim Alarmieren");
		},
		onSuccess: (data) => {
			toast.success(data.message);
		},
	});

	const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";

	const HPGVehicle = ({ state, name }: { state: HpgState; name: string }) => (
		<li className="flex items-center gap-2">
			<span
				className="font-bold text-base"
				style={{
					color: FMS_STATUS_TEXT_COLORS[hpgStateToFMSStatus(state)],
				}}
			>
				{hpgStateToFMSStatus(state)}
			</span>

			<span className="text-base-content">
				<div>
					<span className="font-bold">{name}</span>
				</div>
			</span>
		</li>
	);

	return (
		<div className="p-4 text-base-content">
			<div className="flex items-center w-full justify-between mb-2">
				<h2 className="flex items-center gap-2 text-lg font-bold">
					<SmartphoneNfc /> Rettungsmittel
				</h2>
				{mission.state !== "draft" && dispatcherConnected && (
					<div className="space-x-2">
						<div
							className="tooltip tooltip-primary tooltip-left font-semibold"
							data-tip="Einsatz erneut alarmieren"
						>
							<button
								className="btn btn-xs btn-primary btn-outline"
								onClick={() => {
									sendAlertMutation.mutate({ id: mission.id });
								}}
							>
								<BellRing size={16} />
							</button>
						</div>
					</div>
				)}
			</div>
			<ul className="space-y-2 max-h-[300px] overflow-y-auto overflow-x-auto">
				{missionStations?.map((station, index) => {
					const connectedAircraft = conenctedAircrafts?.find(
						(aircraft) => aircraft.stationId === station.id,
					);

					return (
						<li key={index} className="flex items-center gap-2">
							{connectedAircraft && (
								<span
									className="font-bold text-base"
									style={{
										color: FMS_STATUS_TEXT_COLORS[connectedAircraft.fmsStatus],
									}}
								>
									{connectedAircraft.fmsStatus}
								</span>
							)}
							<span className="text-base-content">
								<div>
									<span className="font-bold">{station.bosCallsign}</span>
									{/* {item.min > 0 && (
								<>
								<br />
								Ankunft in ca. {item.min} min
								</>
								)} */}
								</div>
							</span>
						</li>
					);
				})}
				{mission.hpgAmbulanceState && <HPGVehicle state={mission.hpgAmbulanceState} name="RTW" />}
				{mission.hpgFireEngineState && (
					<HPGVehicle state={mission.hpgFireEngineState} name="Feuerwehr" />
				)}
				{mission.hpgPoliceState && <HPGVehicle state={mission.hpgPoliceState} name="Polizei" />}
			</ul>
			{dispatcherConnected && (
				<div>
					<div className="divider mt-0 mb-0" />
					<div className="flex items-center gap-2">
						{/* TODO: make it a small multiselect */}
						<select
							className="select select-sm select-primary select-bordered flex-1"
							onChange={(e) => {
								const selected = allStations?.find((s) => s.id.toString() === e.target.value);
								if (selected) {
									setSelectedStation(selected);
								} else {
									setSelectedStation(e.target.value as "ambulance" | "police" | "firebrigade");
								}
							}}
							value={typeof selectedStation === "string" ? selectedStation : selectedStation?.id}
						>
							{allStations
								?.filter((s) => !mission.missionStationIds.includes(s.id))
								?.map((station) => (
									<option
										key={station.id}
										value={station.id}
										onClick={() => {
											setSelectedStation(station);
										}}
									>
										{station.bosCallsign}
									</option>
								))}
							<option disabled>Fahrzeuge:</option>
							<option value="firebrigade">Feuerwehr</option>
							<option value="ambulance">RTW</option>
							<option value="police">Polizei</option>
						</select>
						<button
							className="btn btn-sm btn-primary btn-outline"
							onClick={async () => {
								if (typeof selectedStation === "string") {
									await sendAlertMutation.mutate({
										id: mission.id,
										vehicleName: selectedStation,
									});
								} else {
									if (!selectedStation?.id) return;
									await updateMissionMutation.mutateAsync({
										id: mission.id,
										missionEdit: {
											missionStationIds: {
												push: selectedStation?.id,
											},
										},
									});
									await sendAlertMutation.mutate({
										id: mission.id,
										stationId: selectedStation?.id ?? 0,
									});
								}
							}}
						>
							<span className="text-base-content flex items-center gap-2">
								<BellRing size={16} /> Nachalarmieren
							</span>
						</button>
					</div>
				</div>
			)}
		</div>
	);
};

const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
	const session = useSession();
	const [isAddingNote, setIsAddingNote] = useState(false);
	const [note, setNote] = useState("");
	const queryClient = useQueryClient();

	const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";

	const editMissionMutation = useMutation({
		mutationFn: ({ id, mission }: { id: number; mission: Partial<Prisma.MissionUpdateInput> }) =>
			editMissionAPI(id, mission),
		mutationKey: ["missions"],
		onSuccess: () => {
			queryClient.invalidateQueries({ queryKey: ["missions"] });
		},
	});

	if (!session.data?.user) return null;
	return (
		<div className="p-4">
			{dispatcherConnected && (
				<div>
					<div className="flex items-center gap-2">
						{!isAddingNote ? (
							<button
								className="text-base-content text-base cursor-pointer"
								onClick={() => setIsAddingNote(true)}
							>
								<span className="flex items-center gap-2">
									<Plus size={18} /> Notiz hinzufügen
								</span>
							</button>
						) : (
							<div className="flex items-center gap-2 w-full">
								<input
									type="text"
									placeholder=""
									className="input input-sm text-base-content flex-1"
									value={note}
									onChange={(e) => setNote(e.target.value)}
								/>
								<button
									className="btn btn-sm btn-primary btn-outline"
									onClick={() => {
										const newMissionLog = [
											...mission.missionLog,
											{
												type: "message-log",
												auto: false,
												timeStamp: new Date().toISOString(),
												data: {
													message: note,
													user: getPublicUser(session.data?.user, { ignorePrivacy: true }),
												},
											} as MissionMessageLog,
										];
										editMissionMutation
											.mutateAsync({
												id: mission.id,
												mission: {
													// eslint-disable-next-line @typescript-eslint/no-explicit-any
													missionLog: newMissionLog as any,
												},
											})
											.then(() => {
												setIsAddingNote(false);
												setNote("");
											});
									}}
								>
									<Plus size={20} />
								</button>
								<button
									className="btn btn-sm btn-outline"
									onClick={() => {
										setIsAddingNote(false);
										setNote("");
									}}
								>
									<Ban size={20} />
								</button>
							</div>
						)}
					</div>
					<div className="divider m-0" />
				</div>
			)}
			<ul className="space-y-1 max-h-[300px] overflow-y-auto overflow-x-auto">
				{(mission.missionLog as unknown as MissionLog[])
					.slice()
					.reverse()
					.map((entry, index) => {
						if (entry.type === "station-log")
							return (
								<li key={index} className="flex items-center gap-2">
									<span className="text-base-content">
										{new Date(entry.timeStamp).toLocaleTimeString([], {
											hour: "2-digit",
											minute: "2-digit",
										})}
									</span>
									<span
										className="font-bold text-base"
										style={{
											color: FMS_STATUS_TEXT_COLORS[entry.data.newFMSstatus],
										}}
									>
										{entry.data.newFMSstatus}
									</span>
									<span className="text-base-content">{entry.data.station.bosCallsign}</span>
								</li>
							);
						if (entry.type === "message-log" || entry.type === "sds-log")
							return (
								<li key={index} className="flex items-center gap-2">
									<span className="text-base-content">
										{new Date(entry.timeStamp).toLocaleTimeString([], {
											hour: "2-digit",
											minute: "2-digit",
										})}
									</span>
									<span
										className="font-bold text-base flex items-center gap-0.5"
										style={{
											color: FMS_STATUS_TEXT_COLORS[6],
										}}
									>
										{entry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
										{entry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
										{entry.type === "sds-log" && (
											<>
												<svg
													xmlns="http://www.w3.org/2000/svg"
													fill="none"
													viewBox="0 0 24 24"
													strokeWidth="2"
													stroke="currentColor"
													className="size-4"
												>
													<path
														strokeLinecap="round"
														strokeLinejoin="round"
														d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"
													/>
												</svg>

												{entry.data.station.bosCallsignShort}
											</>
										)}
									</span>
									<span className="text-base-content">{entry.data.message}</span>
								</li>
							);
						if (entry.type === "alert-log") {
							const alertReceiver = entry.data.station?.bosCallsignShort || entry.data.vehicle;
							return (
								<li key={index} className="flex items-center gap-2">
									<span className="text-base-content">
										{new Date(entry.timeStamp).toLocaleTimeString([], {
											hour: "2-digit",
											minute: "2-digit",
										})}
									</span>
									<span
										className="font-bold text-base flex items-center gap-0.5"
										style={{
											color: FMS_STATUS_TEXT_COLORS[6],
										}}
									>
										{entry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
										{entry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
										{alertReceiver && (
											<>
												<svg
													xmlns="http://www.w3.org/2000/svg"
													fill="none"
													viewBox="0 0 24 24"
													strokeWidth="2"
													stroke="currentColor"
													className="size-4"
												>
													<path
														strokeLinecap="round"
														strokeLinejoin="round"
														d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"
													/>
												</svg>

												{alertReceiver}
											</>
										)}
									</span>
									<span className="text-base-content">Einsatz alarmiert</span>
								</li>
							);
						}
						return null;
					})}
			</ul>
			{!mission.missionLog.length && (
				<p className="text-gray-500 w-full text-center my-10 font-semibold">
					Keine Notizen verfügbar
				</p>
			)}
		</div>
	);
};

export { FMSStatusHistory, Patientdetails, Rettungsmittel };
export default Einsatzdetails;
