import { FC, useEffect, useRef, useState } from "react";
import { Marker, Popup, useMap, useMapEvent } from "react-leaflet";

import { AssetModel } from "@/contracts/client.schemas";
import { useMarkerIconCreator } from "@/hooks/marker-icon-creator.hook";

import { isNumber } from "../../../services/math";
import { useWatcherStore } from "../store/watcher.store";

import { useMapSlice } from "./map.slice";
import { MapObjectPopup } from "./MapObjectPopup";

interface Props {
	asset: AssetModel;
	withoutPopup?: boolean;
}

export const MapObject: FC<Props> = ({ asset, withoutPopup }) => {
	const { currentOpenPopupObjectId, setCurrentPopupObjectId } = useMapSlice();
	const [isVisible, setIsVisible] = useState(
		asset.id === currentOpenPopupObjectId,
	);
	const popupRef = useRef(null);
	const map = useMap();
	const commonAlarmScopes = useWatcherStore((x) => x.commonAlarmScopes);
	const hasAlarms = commonAlarmScopes.some((x) => x.assetId === asset.id);
	const { create: createIcon } = useMarkerIconCreator();

	useMapEvent("popupclose", () => {
		setCurrentPopupObjectId(undefined);
	});

	useEffect(() => {
		setIsVisible(asset.id === currentOpenPopupObjectId);

		if (currentOpenPopupObjectId === asset.id) {
			setTimeout(() => {
				if (popupRef.current) {
					map.openPopup(popupRef.current);
				}
			}, 500);
		}
	}, [currentOpenPopupObjectId, map, asset.id]);

	if (!isNumber(asset.latitude).is || !isNumber(asset.longitude).is) {
		return null;
	}

	const getIcon = () => {
		return createIcon(hasAlarms);
	};

	const handleMarkerClick = () => {
		if (!withoutPopup) {
			setCurrentPopupObjectId(asset.id);
		}
	};

	return (
		<Marker
			key={`asset-marker-${asset.id}`}
			position={[asset.latitude!, asset.longitude!]}
			icon={getIcon()}
			eventHandlers={{
				click: handleMarkerClick,
			}}
			attribution={asset.id}
			zIndexOffset={hasAlarms ? 1000 : 0}
		>
			{!withoutPopup && (
				<Popup closeButton={false} ref={popupRef} autoPan autoClose>
					{isVisible && (
						<MapObjectPopup asset={asset} hasAlarms={hasAlarms} />
					)}
				</Popup>
			)}
		</Marker>
	);
};
