import debounce from "lodash.debounce";
import maplibregl from "maplibre-gl";
import { useEffect, useRef, useState } from "react";
import Map, { MapProvider } from "react-map-gl";
import { twMerge } from "tailwind-merge";
import { AccidentSimulationResults } from "../dzkh-features/AccidentSimulationResults.jsx";
import { ImportDataButton } from "../dzkh-features/ImportDataButton.jsx";
import { ImportDataModal } from "../dzkh-features/ImportDataModal.jsx";
import { Layers } from "../dzkh-features/Layers/Layers.jsx";
import { Legend } from "../dzkh-features/Legend.jsx";
import { WeatherSlider } from "../dzkh-features/WeatherSlider/WeatherSlider.jsx";
import { LAYER_IDS } from "../dzkh-features/constants.js";
import { icons } from "../icons/icons-config.js";
import { Sidebar } from "../modules/Sidebar/Sidebar";
import { TableWrapper } from "../modules/Table/TableWrapper";
import { useClickedPointConfig } from "../stores/useClickedPointConfig";
import { usePopup } from "../stores/usePopup";
import { useTable } from "../stores/useTable";
import { MapPopup } from "./Popup/Popup";
import { SidebarControl } from "./SidebarControl";

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

  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]);

  useEffect(() => {
    if (tableState.fullScreen && !tableState.isOpened) {
      openTable();
    }
  }, [tableState.fullScreen]);

  const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);

  const toggleCollapseSidebar = () =>
    setIsSidebarCollapsed((prevState) => !prevState);

  const [isImportOpen, setIsImportOpen] = useState(false);

  useEffect(() => {
    icons.map((icon) => {
      const img = new Image(
        icon.size?.width || 64,
        icon.size?.height || 64
      );
      img.src = icon.url;
      img.crossOrigin = "Anonymous";
      img.onload = () => {
        mapRef.current.addImage(icon.name, img);
      }
    });
  }, [icons]);

  return (
    <MapProvider>
      <div className={"w-screen h-screen relative flex overflow-hidden"}>
        <Sidebar isCollapsed={isSidebarCollapsed} ref={sidebarRef} />
        <div className="flex-1 h-screen flex flex-col ">
          <div
            ref={mapContainerRef}
            className={twMerge(tableState.fullScreen ? "" : "flex-1")}
          >
            <Map
              mapLib={maplibregl}
              initialViewState={{
                latitude: 55.7558,
                longitude: 37.6173,
                zoom: 12,
              }}
              dragRotate={false}
              ref={mapRef}
              interactiveLayerIds={[
                LAYER_IDS.consumer,
                LAYER_IDS.source,
                LAYER_IDS.dispatcher,
              ]}
              onClick={handleClick}
              onMouseEnter={handleMouseEnter}
              onMouseLeave={handleMouseLeave}
              id="map"
              mapStyle="https://raw.githubusercontent.com/gtitov/basemaps/refs/heads/master/positron-nolabels.json"
            >
              {popup && (
                <MapPopup
                  lat={popup.coordinates[1]}
                  lng={popup.coordinates[0]}
                  features={popup.features}
                  onClose={() => {
                    setPopup(null);
                    setClickedPointConfig(null);
                  }}
                />
              )}

              <ImportDataButton onClick={() => setIsImportOpen(true)}/>

              <SidebarControl toggleCollapse={toggleCollapseSidebar} />
              <WeatherSlider />

              <Layers />

              <Legend />

              <AccidentSimulationResults />

              {isImportOpen && <ImportDataModal onClose={() => setIsImportOpen(false)} />}
            </Map>
          </div>
          <div className="w-full border-solid border-border border-0 border-t-[1px] z-20">
            <TableWrapper fullWidth={isSidebarCollapsed} />
          </div>
        </div>
      </div>
    </MapProvider>
  );
};
