import { ConnectedAircraft, HpgValidationState, Mission, Station } from "@repo/db";
import { useQuery } from "@tanstack/react-query";
import { SmartPopup, useSmartPopup } from "_components/SmartPopup";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { useMapStore } from "_store/mapStore";
import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "_helpers/fmsStatusColors";
import { MISSION_STATUS_COLORS, MISSION_STATUS_TEXT_COLORS } from "_components/map/MissionMarkers";
import { cn } from "_helpers/cn";
import { checkSimulatorConnected } from "_helpers/simulatorConnected";
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
import { getMissionsAPI } from "_querys/missions";
import { useEffect, useMemo, useState } from "react";
import { useMap } from "react-leaflet";
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";

const PopupContent = ({
	aircrafts,
	missions,
}: {
	aircrafts: (ConnectedAircraft & { Station: Station })[];
	missions: Mission[];
}) => {
	const { anchor } = useSmartPopup();
	const { setOpenAircraftMarker, setOpenMissionMarker } = useMapStore((state) => state);
	const map = useMap();

	let borderColor = "";

	if (anchor.includes("top")) {
		if (missions.length > 0) {
			borderColor = MISSION_STATUS_TEXT_COLORS[missions[0]!.state];
		} else if (aircrafts.length > 0) {
			borderColor = FMS_STATUS_TEXT_COLORS[aircrafts[0]!.fmsStatus] || "white";
		}
	} else if (anchor.includes("bottom")) {
		if (aircrafts.length > 0) {
			borderColor = FMS_STATUS_TEXT_COLORS[aircrafts[aircrafts.length - 1]!.fmsStatus] || "white";
		} else if (missions.length > 0) {
			borderColor = MISSION_STATUS_TEXT_COLORS[missions[0]!.state];
		}
	}

	return (
		<>
			<div className="relative flex flex-col text-white min-w-[200px]">
				<div
					className={cn(
						"absolute w-[calc(100%+2px)] h-4 z-99 pointer-events-none",
						anchor.includes("left") ? "-left-[2px]" : "-right-[2px]",
						anchor.includes("top") ? "-top-[2px]" : "-bottom-[2px]",
					)}
					style={{
						borderLeft: anchor.includes("left") ? `3px solid ${borderColor}` : "",
						borderRight: anchor.includes("right") ? `3px solid ${borderColor}` : "",
						borderTop: anchor.includes("top") ? `3px solid ${borderColor}` : "",
						borderBottom: anchor.includes("bottom") ? `3px solid ${borderColor}` : "",
					}}
				/>
				{missions.map((mission) => {
					const needsAction =
						HPGValidationRequired(mission.missionStationIds, aircrafts, mission.hpgMissionString) &&
						mission.hpgValidationState !== HpgValidationState.VALID &&
						mission.state === "draft";

					const markerColor = needsAction
						? MISSION_STATUS_COLORS["attention"]
						: MISSION_STATUS_COLORS[mission.state];
					return (
						<div
							key={mission.id}
							className={cn("relative inline-flex items-center gap-2 text-nowrap w-full")}
							style={{
								backgroundColor: markerColor,
								cursor: "pointer",
							}}
						>
							<span
								className="mx-2 my-0.5 flex-1 cursor-pointer"
								onClick={() => {
									setOpenMissionMarker({
										open: [
											{
												id: mission.id,
												tab: "home",
											},
										],
										close: [],
									});
									map.setView([mission.addressLat, mission.addressLng], 12, {
										animate: true,
									});
								}}
							>
								{mission.missionKeywordAbbreviation}
							</span>
						</div>
					);
				})}
				{aircrafts
					.filter((a) => checkSimulatorConnected(a.lastHeartbeat))
					.map((aircraft) => (
						<div
							key={aircraft.id}
							className="relative w-auto inline-flex items-center gap-2 text-nowrap cursor-pointer"
							style={{
								backgroundColor: FMS_STATUS_COLORS[aircraft.fmsStatus],
							}}
							onClick={() => {
								setOpenAircraftMarker({
									open: [
										{
											id: aircraft.id,
											tab: "aircraft",
										},
									],
									close: [],
								});
								map.setView([aircraft.posLat!, aircraft.posLng!], 12, {
									animate: true,
								});
							}}
						>
							<span
								className="mx-2 my-0.5 text-gt font-bold"
								style={{
									color: FMS_STATUS_TEXT_COLORS[aircraft.fmsStatus],
								}}
							>
								{aircraft.fmsStatus}
							</span>
							<span>{aircraft.Station.bosCallsign}</span>
						</div>
					))}
			</div>
		</>
	);
};

export const MarkerCluster = () => {
	const map = useMap();
	const { data: aircrafts } = useQuery({
		queryKey: ["aircrafts"],
		queryFn: getConnectedAircraftsAPI,
	});

	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]);

	// Track zoom level in state
	const [zoom, setZoom] = useState(() => map.getZoom());

	useEffect(() => {
		const handleZoom = () => setZoom(map.getZoom());
		map.on("zoomend", handleZoom);
		return () => {
			map.off("zoomend", handleZoom);
		};
	}, [map]);

	const clusters = useMemo(() => {
		if (zoom >= 8) return [];
		let newCluster: {
			aircrafts: (ConnectedAircraft & { Station: Station })[];
			missions: Mission[];
			lat: number;
			lng: number;
		}[] = [];
		aircrafts
			?.filter((a) => checkSimulatorConnected(a.lastHeartbeat))
			.forEach((aircraft) => {
				const lat = aircraft.posLat!;
				const lng = aircraft.posLng!;

				const existingClusterIndex = newCluster.findIndex(
					(c) => Math.abs(c.lat - lat) < 1 && Math.abs(c.lng - lng) < 1,
				);
				const existingCluster = newCluster[existingClusterIndex];
				if (existingCluster) {
					newCluster = [...newCluster].map((c, i) => {
						if (i === existingClusterIndex) {
							return {
								...c,
								aircrafts: [...c.aircrafts, aircraft],
							};
						}
						return c;
					});
				} else {
					newCluster = [
						...newCluster,
						{
							aircrafts: [aircraft],
							missions: [],
							lat,
							lng,
						},
					];
				}
			});
		filteredMissions?.forEach((mission) => {
			const lat = mission.addressLat;
			const lng = mission.addressLng;
			const existingClusterIndex = newCluster.findIndex(
				(c) => Math.abs(c.lat - lat) < 1 && Math.abs(c.lng - lng) < 1,
			);
			const existingCluster = newCluster[existingClusterIndex];

			if (existingCluster) {
				newCluster = [...newCluster].map((c, i) => {
					if (i === existingClusterIndex) {
						return {
							...c,
							missions: [...c.missions, mission],
						};
					}
					return c;
				});
			} else {
				newCluster = [
					...newCluster,
					{
						aircrafts: [],
						missions: [mission],
						lat,
						lng,
					},
				];
			}
		});

		const clusterWithAvgPos = newCluster.map((c) => {
			const aircraftPos = c.aircrafts.map((a) => [a.posLat, a.posLng]);
			const missionPos = c.missions.map((m) => [m.addressLat, m.addressLng]);
			const allPos = [...aircraftPos, ...missionPos];

			const avgLat = allPos.reduce((sum, pos) => sum + pos[0]!, 0) / allPos.length;
			const avgLng = allPos.reduce((sum, pos) => sum + pos[1]!, 0) / allPos.length;

			return {
				...c,
				lat: avgLat,
				lng: avgLng,
			};
		});

		return clusterWithAvgPos;
	}, [aircrafts, filteredMissions, zoom]);

	return (
		<>
			{clusters.map((c, i) => (
				<SmartPopup
					options={{
						ignoreMarker: true,
					}}
					id={`cluster-${i}`}
					wrapperClassName="relative"
					key={i}
					position={[c.lat, c.lng]}
					autoPan={false}
					autoClose={false}
					className="w-[202px]"
				>
					<PopupContent aircrafts={c.aircrafts} missions={c.missions} />
				</SmartPopup>
			))}
		</>
	);
};
