import { Marker, useMap } from "react-leaflet";
import { DivIcon, Marker as LMarker, Popup as LPopup } from "leaflet";
import { useMapStore } from "_store/mapStore";
import { usePannelStore } from "_store/pannelStore";
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { cn } from "_helpers/cn";
import { ClipboardList, Cross, House, Minimize2, SmartphoneNfc, PencilLine } from "lucide-react";
import { calculateAnchor, SmartPopup, useSmartPopup } from "_components/SmartPopup";
import { Mission, MissionState } from "@repo/db";
import Einsatzdetails, {
	FMSStatusHistory,
	Patientdetails,
	Rettungsmittel,
} from "./_components/MissionMarkerTabs";
import { useQuery } from "@tanstack/react-query";
import { getMissionsAPI } from "_querys/missions";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
import { getConnectedAircraftsAPI } from "_querys/aircrafts";

export const MISSION_STATUS_COLORS: Record<MissionState | "attention", string> = {
	draft: "#0092b8",
	running: "#155dfc",
	finished: "#155dfc",
	attention: "rgb(186,105,0)",
};

export const MISSION_STATUS_TEXT_COLORS: Record<MissionState, string> = {
	draft: "#00d3f2",
	running: "#50a2ff",
	finished: "#50a2ff",
};

const MissionPopupContent = ({
	mission,
	hpgNeedsAttention,
}: {
	mission: Mission;
	hpgNeedsAttention?: boolean;
}) => {
	const { setEditingMission } = usePannelStore();
	const setMissionMarker = useMapStore((state) => state.setOpenMissionMarker);
	const currentTab = useMapStore(
		(state) => state.openMissionMarker.find((m) => m.id === mission.id)?.tab ?? "home",
	);

	const handleTabChange = useCallback(
		(tab: "home" | "details" | "patient" | "log") => {
			setMissionMarker({
				open: [
					{
						id: mission.id,
						tab,
					},
				],
				close: [],
			});
		},
		[setMissionMarker, mission.id],
	);

	const renderTabContent = useMemo(() => {
		switch (currentTab) {
			case "home":
				return <Einsatzdetails mission={mission} hpgNeedsAttention={hpgNeedsAttention} />;
			case "details":
				return <Rettungsmittel mission={mission} />;
			case "patient":
				return <Patientdetails mission={mission} />;
			case "log":
				return <FMSStatusHistory mission={mission} />;
			default:
				return <span className="text-gray-100">Error</span>;
		}
	}, [currentTab, mission]);

	const setOpenMissionMarker = useMapStore((state) => state.setOpenMissionMarker);
	const { anchor } = useSmartPopup();
	const { setMissionFormValues, setOpen } = usePannelStore((state) => state);

	return (
		<>
			<div
				className="absolute p-1 z-99 top-0 right-0 transform -translate-y-full bg-base-100 cursor-pointer"
				onClick={() => {
					setOpenMissionMarker({
						open: [],
						close: [mission.id],
					});
				}}
			>
				<Minimize2 className="text-white" size={16} />
			</div>

			<div
				className={cn(
					"absolute w-[calc(100%+2px)] h-4 z-99",
					anchor.includes("left") ? "-left-[2px]" : "-right-[2px]",
					anchor.includes("top") ? "-top-[2px]" : "-bottom-[2px]",
				)}
				style={{
					borderLeft: anchor.includes("left")
						? `3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
						: "",
					borderRight: anchor.includes("right")
						? `3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
						: "",
					borderTop: anchor.includes("top")
						? `3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
						: "",
					borderBottom: anchor.includes("bottom")
						? `3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
						: "",
				}}
			/>
			<div>
				<div
					className="flex gap-[2px] text-white pb-0.5"
					style={{
						backgroundColor: `${MISSION_STATUS_TEXT_COLORS[mission.state]}`,
					}}
				>
					<div
						className="p-2 px-3 flex justify-center items-center cursor-pointer"
						style={{
							backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
							borderBottom:
								currentTab === "home"
									? `5px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
									: "5px solid transparent",
						}}
						onClick={() => handleTabChange("home")}
					>
						<House className="text-sm" />
					</div>
					<div
						className="p-2 px-4 flex justify-center items-center cursor-pointer"
						style={{
							backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
							borderBottom:
								currentTab === "patient"
									? `5px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
									: "5px solid transparent",
						}}
						onClick={() => handleTabChange("patient")}
					>
						<Cross className="text-sm" />
					</div>
					<div
						className="p-2 px-4 flex justify-center items-center cursor-pointer"
						style={{
							backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
							borderBottom:
								currentTab === "details"
									? `5px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
									: "5px solid transparent",
						}}
						onClick={() => handleTabChange("details")}
					>
						<SmartphoneNfc className="text-sm" />
					</div>
					{mission.state === "draft" && (
						<div
							className="p-2 px-4 flex justify-center items-center cursor-pointer ml-auto"
							style={{
								backgroundColor: `${MISSION_STATUS_COLORS["attention"]}`,
								borderBottom: "5px solid transparent",
							}}
							onClick={() => {
								setMissionFormValues({
									...mission,
									addressMissionLocation: mission.addressMissionLocation ?? undefined,
									addressAdditionalInfo: mission.addressAdditionalInfo ?? undefined,
									state: "draft",
									hpgLocationLat: mission.hpgLocationLat ?? undefined,
									hpgLocationLng: mission.hpgLocationLng ?? undefined,
								});
								setEditingMission(true, mission.id);
								setOpen(true);
							}}
						>
							<PencilLine className="text-sm" />
						</div>
					)}
					<div
						className={cn(
							"p-2 px-4 flex justify-center items-center cursor-pointer",
							mission.state !== "draft" && "ml-auto",
						)}
						style={{
							backgroundColor: `${MISSION_STATUS_COLORS[mission.state]}`,
							borderBottom:
								currentTab === "log"
									? `5px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]}`
									: "5px solid transparent",
						}}
						onClick={() => handleTabChange("log")}
					>
						<ClipboardList className="text-sm" />
					</div>
				</div>
			</div>
			<div className="h-full min-h-[200px]">{renderTabContent}</div>
		</>
	);
};

const MissionMarker = ({ mission }: { mission: Mission }) => {
	const map = useMap();
	const [hideMarker, setHideMarker] = useState(false);
	const markerRef = useRef<LMarker>(null);
	const popupRef = useRef<LPopup>(null);

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

	const { openMissionMarker, setOpenMissionMarker } = useMapStore((store) => store);

	const needsAction =
		HPGValidationRequired(mission.missionStationIds, aircrafts, mission.hpgMissionString) &&
		mission.hpgValidationState !== "VALID" &&
		mission.state === "draft";

	useEffect(() => {
		const handleClick = () => {
			const open = openMissionMarker.some((m) => m.id === mission.id);
			if (open) {
				setOpenMissionMarker({
					open: [],
					close: [mission.id],
				});
			} else {
				setOpenMissionMarker({
					open: [
						{
							id: mission.id,
							tab: "home",
						},
					],
					close: [],
				});
			}
		};
		const markerCopy = markerRef.current;
		markerCopy?.on("click", handleClick);
		return () => {
			markerCopy?.off("click", handleClick);
		};
	}, [mission.id, openMissionMarker, setOpenMissionMarker]);

	const [anchor, setAnchor] = useState<"topleft" | "topright" | "bottomleft" | "bottomright">(
		"topleft",
	);

	const handleConflict = useCallback(() => {
		const newAnchor = calculateAnchor(`mission-${mission.id.toString()}`, "marker");
		setAnchor(newAnchor);
	}, [mission.id]);

	useEffect(() => {
		handleConflict();
	}, [handleConflict]);

	useEffect(() => {
		setTimeout(() => {
			handleZoom();
		}, 100);

		const handleZoom = () => {
			const zoom = map.getZoom();
			setHideMarker(zoom < 8);
			handleConflict();
		};

		map.on("zoomend", handleZoom);
		return () => {
			map.off("zoomend", handleZoom);
		};
	}, [map, openMissionMarker, handleConflict]);

	const getMarkerHTML = (
		mission: Mission,
		anchor: "topleft" | "topright" | "bottomleft" | "bottomright",
	) => {
		const markerColor = needsAction
			? MISSION_STATUS_COLORS["attention"]
			: MISSION_STATUS_COLORS[mission.state];
		return `<div 
						id="marker-mission-${mission.id}"
						class="${cn(
							"relative w-auto transform inline-flex items-center gap-2 px-2 z-100",
							anchor.includes("right") && "-translate-x-full",
							anchor.includes("bottom") && "-translate-y-full",
							hideMarker ? "opacity-0 pointer-events-none" : "opacity-100",
						)}"
						style="
							background-color: ${markerColor};
							${openMissionMarker.some((m) => m.id === mission.id) ? "opacity: 0; pointer-events: none;" : ""}
						">
						
						<div 
							class="${cn(
								"absolute w-4 h-4 z-99",
								anchor.includes("left") ? "-left-[2px]" : "-right-[2px]",
								anchor.includes("top") ? "-top-[2px]" : "-bottom-[2px]",
							)}" 
							style="
								${anchor.includes("left") ? `border-left: 3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]};` : `border-right: 3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]};`}
								${anchor.includes("top") ? `border-top: 3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]};` : `border-bottom: 3px solid ${MISSION_STATUS_TEXT_COLORS[mission.state]};`}
							"
						></div>
						<span class="text-white text-[15px] text-nowrap">
							${mission.missionKeywordAbbreviation} ${mission.missionKeywordName}
						</span>
						<div 
						data-anchor-lat="${mission.addressLat}"
							data-anchor-lng="${mission.addressLng}"
							data-id="${mission.id}"
							id="marker-domain-mission-${mission.id}" 
							class="${cn(
								"map-collision absolute w-[200%] h-[200%] top-0 left-0 transform pointer-events-none",
								anchor.includes("left") && "-translate-x-1/2",
								anchor.includes("top") && "-translate-y-1/2",
							)}"
						></div>
					</div>`;
	};

	return (
		<Fragment key={mission.id}>
			<Marker
				ref={markerRef}
				position={[mission.addressLat, mission.addressLng]}
				icon={
					new DivIcon({
						iconAnchor: [0, 0],
						html: getMarkerHTML(mission, anchor),
					})
				}
			/>
			{openMissionMarker.some((m) => m.id === mission.id) && !hideMarker && (
				<SmartPopup
					options={{
						ignoreCluster: true,
					}}
					id={`mission-${mission.id.toString()}`}
					ref={popupRef}
					position={[mission.addressLat, mission.addressLng]}
					autoClose={false}
					closeOnClick={false}
					autoPan={false}
					wrapperClassName="relative"
					className="w-[502px]"
				>
					<div style={{ height: "auto", maxHeight: "90vh", overflowY: "auto" }}>
						<MissionPopupContent mission={mission} hpgNeedsAttention={needsAction} />
					</div>
				</SmartPopup>
			)}
		</Fragment>
	);
};

export const MissionLayer = () => {
	const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";
	const { data: missions = [] } = useQuery({
		queryKey: ["missions"],
		queryFn: () =>
			getMissionsAPI({
				OR: [{ state: "draft" }, { state: "running" }],
			}),
	});

	const filteredMissions = useMemo(() => {
		if (!dispatcherConnected) {
			return missions.filter((m: Mission) => m.state === "running");
		}
		return missions;
	}, [missions, dispatcherConnected]);

	// IDEA:  Add Marker to Map Layer / LayerGroup
	return (
		<>
			{filteredMissions.map((mission) => {
				return <MissionMarker key={mission.id} mission={mission as Mission} />;
			})}
		</>
	);
};
