import maplibregl from "maplibre-gl";
import Map, { MapProvider } from "react-map-gl";
import { useEffect, useRef } from "react";
import { Sidebar } from "../modules/Sidebar/Sidebar";
import { Layers } from "./Layers";
import { MapPopup } from "./Popup";
import { Basemap } from "./Basemap";
import { SignOut } from "../SignOut";
import debounce from "lodash.debounce";
import { Table } from "../modules/Table/Table";
import { usePopup } from "../stores/usePopup";
import { useClickedPointConfig } from "../stores/useClickedPointConfig";
import { Legend } from "../modules/Sidebar/Legend";
import { AddressSearch } from "../modules/Sidebar/AddressSearch";

export const MapComponent = () => {
  const mapRef = useRef(null);
  const mapContainerRef = useRef(null);
  const { popup, setPopup } = usePopup();
  const { setClickedPointConfig } = useClickedPointConfig();

  const handleClick = (event) => {
    if (!event.features) {
      setPopup(null);
      setClickedPointConfig(null);
      return;
    }

    const feature = event.features[0];
    if (!feature) {
      setPopup(null);
      setClickedPointConfig(null);
      return;
    }

    const { lng: pointLng } = event.lngLat;

    if (feature.geometry.type === "Point") {
      const coordinates = feature.geometry.coordinates.slice();
      while (Math.abs(pointLng - coordinates[0]) > 180) {
        coordinates[0] += pointLng > coordinates[0] ? 360 : -360;
      }

      setPopup({ features: event.features, coordinates });
    }
  };

  const handleMouseEnter = (event) => {
    const feature = event.features[0];
    if (!feature) return;

    mapRef.current.getCanvas().style.cursor = "pointer";
  };

  const handleMouseLeave = (event) => {
    const feature = event.features[0];
    if (!feature) {
      return;
    }
    mapRef.current.getCanvas().style.cursor = "";
  };

  useEffect(() => {
    const resizeObserver = new ResizeObserver(
      debounce(() => {
        mapRef?.current?.resize();
      }, 16)
    );
    if (mapContainerRef.current) {
      resizeObserver.observe(mapContainerRef.current);
    }

    return () => {
      resizeObserver.disconnect();
    };
  }, [mapContainerRef.current]);

  return (
    <MapProvider>
      <div ref={mapContainerRef} className="w-full flex-1">
        <Map
          mapLib={maplibregl}
          // mapStyle={`https://api.maptiler.com/maps/voyager/style.json?key=${MAP_TILER_KEY}`}
          // style={{ width: "100%", height: "100%" }}
          initialViewState={{
            latitude: 55.7558,
            longitude: 37.6173,
            zoom: 9,
          }}
          dragRotate={false}
          ref={mapRef}
          interactiveLayerIds={["match-points", "unmatch-points"]}
          onClick={handleClick}
          onMouseEnter={handleMouseEnter}
          onMouseLeave={handleMouseLeave}
          id="map"
        >
          {popup && (
            <MapPopup
              lat={popup.coordinates[1]}
              lng={popup.coordinates[0]}
              features={popup.features}
              onClose={() => {
                setPopup(null);
                setClickedPointConfig(null);
              }}
            />
          )}

          <Basemap />
          <Layers />

          <Sidebar />
          <AddressSearch />

          <Legend />
          <SignOut />
        </Map>
      </div>
      <Table />
    </MapProvider>
  );
};
