import { useEffect, useState } from "react";
import { useMap } from "react-leaflet";

import { useAuthorizedContext } from "@/contexts/authorized/useAuthorizedContext";
import { AssetModel } from "@/contracts/client.schemas";
import { isNumber } from "@/services/math";

import { useWatcherStore } from "../store/watcher.store";

import { MapObject } from "./MapObject";

export const ObjectMarkerList = () => {
	const { assets } = useWatcherStore();
	const {
		user: { id: userId },
	} = useAuthorizedContext();
	const [markers, setMarkers] = useState<AssetModel[]>([]);
	const map = useMap();

	useEffect(() => {
		const enabledAssetsOnMap = assets
			.map((x) => ({
				asset: x,
				lat: isNumber(x.latitude),
				lon: isNumber(x.longitude),
			}))
			.filter((x) => x.lat.is && x.lon.is)
			.map((x) => x.asset);

		setMarkers(enabledAssetsOnMap);

		if (enabledAssetsOnMap.length === 0) {
			return;
		}

		map.fitBounds([
			[getMinLat(enabledAssetsOnMap), getMinLon(enabledAssetsOnMap)],
			[getMaxLat(enabledAssetsOnMap), getMaxLon(enabledAssetsOnMap)],
		]);

		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [assets, userId]);

	return (
		<>
			{markers.map((x) => (
				<MapObject key={x.id} asset={x} />
			))}
		</>
	);
};

const getMinLat = (assetList: AssetModel[]) => {
	return Math.min(...getCoordList(assetList, (x) => x.latitude));
};
const getMaxLat = (assetList: AssetModel[]) => {
	return Math.max(...getCoordList(assetList, (x) => x.latitude));
};
const getMinLon = (assetList: AssetModel[]) => {
	return Math.min(...getCoordList(assetList, (x) => x.longitude));
};
const getMaxLon = (assetList: AssetModel[]) => {
	return Math.max(...getCoordList(assetList, (x) => x.longitude));
};

const getCoordList = (
	assetList: AssetModel[],
	selector: (asset: AssetModel) => number | null | undefined,
) => {
	return assetList
		.map((x) => isNumber(selector(x)))
		.filter((x) => x.is)
		.map((x) => x.value);
};
