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 "@repo/shared-components";
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";
import { usePilotConnectionStore } from "_store/pilot/connectionStore";

const PopupContent = ({
	aircrafts,
	missions,
}: {
	aircrafts: (ConnectedAircraft & { Station: Station })[];
	missions: Mission[];
}) => {
	const { anchor } = useSmartPopup();
	const {
		setOpenAircraftMarker,
		setOpenMissionMarker,
		openAircraftMarker,
		openMissionMarker,
		userSettings,
	} = 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 min-w-fit flex-col text-white">
				<div
					className={cn(
						"z-99 pointer-events-none absolute h-4 w-[calc(100%+2px)]",
						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 w-full items-center gap-2 text-nowrap")}
							style={{
								backgroundColor: markerColor,
								cursor: "pointer",
							}}
						>
							<span
								className="mx-2 my-0.5 flex-1 cursor-pointer"
								onClick={() => {
									if (userSettings.settingsAutoCloseMapPopup) {
										setOpenMissionMarker({
											open: [
												{
													id: mission.id,
													tab: "home",
												},
											],
											close: openMissionMarker?.map((m) => m.id) || [],
										});
									} else {
										setOpenMissionMarker({
											open: [
												{
													id: mission.id,
													tab: "home",
												},
											],
											close: [],
										});
									}
									map.setView([mission.addressLat, mission.addressLng], 12, {
										animate: true,
									});
								}}
							>
								{mission.missionKeywordAbbreviation}
							</span>
						</div>
					);
				})}
				{aircrafts.map((aircraft) => (
					<div
						key={aircraft.id}
						className="relative inline-flex w-auto cursor-pointer items-center gap-2 text-nowrap px-2"
						style={{
							backgroundColor: FMS_STATUS_COLORS[aircraft.fmsStatus],
						}}
						onClick={() => {
							if (userSettings.settingsAutoCloseMapPopup) {
								setOpenAircraftMarker({
									open: [
										{
											id: aircraft.id,
											tab: "home",
										},
									],
									close: openAircraftMarker?.map((m) => m.id) || [],
								});
							} else {
								setOpenAircraftMarker({
									open: [
										{
											id: aircraft.id,
											tab: "home",
										},
									],
									close: [],
								});
							}
							map.setView([aircraft.posLat!, aircraft.posLng!], 12, {
								animate: true,
							});
						}}
					>
						<span
							className="text-gt my-0.5 font-bold"
							style={{
								color: FMS_STATUS_TEXT_COLORS[aircraft.fmsStatus],
							}}
						>
							{aircraft.fmsStatus}
						</span>
						<span>
							{aircraft.Station.bosCallsign.length > 15
								? aircraft.Station.bosCallsignShort
								: aircraft.Station.bosCallsign}
						</span>
					</div>
				))}
			</div>
		</>
	);
};

export const MarkerCluster = () => {
	const map = useMap();
	const dispatchState = useDispatchConnectionStore((s) => s);
	const pilotState = usePilotConnectionStore((s) => s);
	const dispatcherConnected = dispatchState.status === "connected";
	const { data: aircrafts } = useQuery({
		queryKey: ["aircrafts"],
		queryFn: () => getConnectedAircraftsAPI(),
		refetchInterval: 10_000,
	});

	const { data: missions = [] } = useQuery({
		queryKey: ["missions"],
		queryFn: () =>
			getMissionsAPI({
				OR: [{ state: "draft" }, { state: "running" }],
			}),
	});

	const filteredMissions = useMemo(() => {
		return missions.filter((m: Mission) => {
			if (m.state === "draft" && !dispatcherConnected) return false;
			if (dispatchState.hideDraftMissions && m.state === "draft") return false;
			if (
				pilotState.status === "connected" &&
				!pilotState.showOtherMissions &&
				pilotState.selectedStation
			)
				return m.missionStationIds.includes(pilotState.selectedStation.id);
			return true;
		});
	}, [
		missions,
		dispatcherConnected,
		dispatchState.hideDraftMissions,
		pilotState.selectedStation,
		pilotState.showOtherMissions,
		pilotState.status,
	]);

	const filteredAircrafts = useMemo(() => {
		return aircrafts?.filter((a: ConnectedAircraft) => {
			if (pilotState.status === "connected" && !pilotState.showOtherAircrafts) {
				return a.stationId === pilotState.connectedAircraft?.stationId;
			}
			return true;
		});
	}, [
		aircrafts,
		pilotState.status,
		pilotState.showOtherAircrafts,
		pilotState.connectedAircraft?.stationId,
	]);

	// 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;
		}[] = [];
		filteredAircrafts?.forEach((aircraft) => {
			const lat = aircraft.posLat!;
			const lng = aircraft.posLng!;

			const existingClusterIndex = newCluster.findIndex(
				(c) => Math.abs(c.lat - lat) < 1.55 && 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;
	}, [filteredAircrafts, 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="min-w-fit"
				>
					<PopupContent aircrafts={c.aircrafts} missions={c.missions} />
				</SmartPopup>
			))}
		</>
	);
};
