import maplibregl from "maplibre-gl";
import Map, { MapProvider } from "react-map-gl";
import { useEffect, useRef, useState } from "react";
import { Sidebar } from "../modules/Sidebar/Sidebar";
import { Layers } from "./Layers/Layers";
import { MapPopup } from "./Popup/Popup";
import { Basemap } from "./Basemap";
import { SignOut } from "../SignOut";
import debounce from "lodash.debounce";
import { usePopup } from "../stores/usePopup";
import { useClickedPointConfig } from "../stores/useClickedPointConfig";
import { Legend } from "./Legend";
import { TableWrapper } from "../modules/Table/TableWrapper";
import { useFilters } from "../stores/useFilters";
import { useMode } from "../stores/useMode";
import {
  MODE_TO_LAYER_VISIBILITY_MAPPER,
  MODE_TO_STATUS_MAPPER,
} from "../config";
import { SidebarControl } from "./SidebarControl";
import { LayersControl } from "./LayersControl/LayersControl";
import { useTable } from "../stores/useTable";
import { twMerge } from "tailwind-merge";
import { useLayersVisibility } from "../stores/useLayersVisibility";
import { LAYER_IDS } from "./Layers/constants";
import { Header } from "./Header";

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

  useEffect(() => {
    setStatus(MODE_TO_STATUS_MAPPER[mode]);
    setLayersVisibility(MODE_TO_LAYER_VISIBILITY_MAPPER[mode]);
    setPopup(null);
    setClickedPointConfig(null);
  }, [mode]);

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

  return (
    <MapProvider>
      <div className={"w-screen h-screen relative flex overflow-hidden"}>
        <Header />
        <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}
              // 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={[
                LAYER_IDS["initial-match"],
                LAYER_IDS["initial-unmatch"],
                LAYER_IDS.approve,
                LAYER_IDS.working,
              ]}
              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);
                  }}
                />
              )}

              <SidebarControl toggleCollapse={toggleCollapseSidebar} />

              <Basemap />
              <Layers />

              <Legend />
              <SignOut />
              <LayersControl />
            </Map>
          </div>
          <div className="w-full border-solid border-border border-0 border-t-[1px] z-20">
            <TableWrapper fullWidth={isSidebarCollapsed} />
          </div>
        </div>
      </div>
    </MapProvider>
  );
};
