import { useMapStore } from "_store/mapStore";
import { Marker as LMarker } from "leaflet";
import { Fragment, useEffect, useRef } from "react";
import { Marker, Polygon, Popup } from "react-leaflet";
import L from "leaflet";
import { useQuery } from "@tanstack/react-query";
import { getMissionsAPI } from "_querys/missions";
import { OSMWay } from "@repo/db";
import { usePannelStore } from "_store/pannelStore";

export const SearchElements = () => {
	const { searchElements, searchPopup, setSearchPopup, setContextMenu, openMissionMarker } =
		useMapStore();
	const { missionFormValues, setMissionFormValues } = usePannelStore((state) => state);
	const missions = useQuery({
		queryKey: ["missions"],
		queryFn: () =>
			getMissionsAPI({
				OR: [
					{
						state: "draft",
					},
					{
						state: "running",
					},
				],
			}),
	});
	const poppupRef = useRef<LMarker>(null);
	const searchPopupElement = searchElements.find(
		(element) => element.wayID === searchPopup?.elementId,
	);

	const SearchElement = ({
		element,
		isActive = false,
	}: {
		element: (typeof searchElements)[1];
		isActive?: boolean;
	}) => {
		const ref = useRef<L.Polygon>(null);

		useEffect(() => {
			if (ref.current) {
				ref.current.on("click", () => {
					const center = ref.current?.getBounds().getCenter();
					if (center && searchPopup?.elementId !== element.wayID) {
						setSearchPopup({
							lat: center.lat,
							lng: center.lng,
							elementId: element.wayID,
						});
					} else {
						setSearchPopup(null);
					}
					setContextMenu(null);
				});
			}
		}, [element.wayID]);

		if (!element.nodes) return null;
		return (
			<Polygon
				positions={element.nodes.map((node) => [node.lat, node.lon])}
				color={searchPopup?.elementId === element.wayID || isActive ? "#ff4500" : "#46b7a3"}
				eventHandlers={{
					click: () => {
						const addressOSMways = missionFormValues?.addressOSMways || [];

						addressOSMways.push(JSON.parse(JSON.stringify(element)));

						setMissionFormValues({
							...missionFormValues,
							addressOSMways,
						});
					},
				}}
				ref={ref}
			/>
		);
	};

	const SearchElementPopup = ({ element }: { element: (typeof searchElements)[1] }) => {
		if (!searchPopup) return null;
		return (
			<Popup
				autoPan={false}
				position={[searchPopup.lat, searchPopup.lng]}
				autoClose={false}
				closeOnClick={false}
			>
				<div className="bg-base-100/70 border border-rescuetrack w-[250px] text-white pointer-events-auto p-2">
					<h3 className="text-lg font-bold">
						{element.tags?.building === "yes" ? "Gebäude" : element.tags?.building}
						{!element.tags?.building && "unbekannt"}
					</h3>
					<p className="">
						{element.tags?.["addr:street"]} {element.tags?.["addr:housenumber"]}
					</p>
					<p className="">
						{element.tags?.["addr:suburb"]} {element.tags?.["addr:postcode"]}
					</p>
					<div className="flex flex-col gap-2 mt-2">
						<button className="btn bg-rescuetrack-highlight">Zum Einsatz Hinzufügen</button>
					</div>
				</div>
			</Popup>
		);
	};

	return (
		<>
			{openMissionMarker.map(({ id }) => {
				const mission = missions.data?.find((m) => m.id === id);
				if (!mission) return null;
				return (
					<Fragment key={`mission-osm-${mission.id}`}>
						{(mission.addressOSMways as (OSMWay | null)[])
							.filter((element): element is OSMWay => element !== null)
							.map((element: OSMWay, i) => (
								<SearchElement
									key={`mission-elem-${element.wayID}-${i}`}
									element={element}
									isActive
								/>
							))}
					</Fragment>
				);
			})}
			{searchElements.map((element, i) => {
				if (
					missions.data?.some(
						(mission) =>
							(mission.addressOSMways as (OSMWay | null)[])
								.filter((e): e is OSMWay => e !== null)
								.some((e) => e.wayID === element.wayID) &&
							openMissionMarker.some((m) => m.id === mission.id),
					)
				)
					return null;
				return <SearchElement key={`mission-elem-${element.wayID}-${i}`} element={element} />;
			})}
			{searchPopup && (
				<Marker
					position={[searchPopup.lat, searchPopup.lng]}
					ref={poppupRef}
					icon={new L.DivIcon()}
					opacity={0}
				>
					{!searchPopupElement && <div className="w-20 border border-rescuetrack"></div>}
				</Marker>
			)}
			{searchPopupElement && <SearchElementPopup element={searchPopupElement} />}
		</>
	);
};
