import React, { useEffect, useRef } from "react";
import mapboxgl from "mapbox-gl";
import "mapbox-gl/dist/mapbox-gl.css";
const calculateZoomValue = () => 4;

const Map = (props: any) => {  
  const zoomPin = !props?.keys || !props?.keys === 1;
  const mapContainerRef = useRef(null);
  useEffect(() => {
    mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_GL_TOKEN as string;
    let maxBoundsCondition;

    if (!props.coordinates) {
      maxBoundsCondition = props?.dash === "1" ? [-160, 9] : [-160, 14];
    } else {
      maxBoundsCondition = [-180, -90];
    }

    const map = new mapboxgl.Map({
      container: mapContainerRef.current as any,
      style: "mapbox://styles/mapbox/streets-v10",
      center: [-97.048, 38.485],
      zoom: props?.dash === "1" ? 10 : 1,
      maxBounds: [
        maxBoundsCondition as any,
        !props?.coordinates ? [-24, 72] : [180, 90],
      ],
    });

    map.on("load", () => {
      map.loadImage("/images/circle.png", (error, image: any) => {
        if (error) throw error;
        map.addImage("custom-icon", image);
      });
    });

    map.on("load", () => {
      map.addSource("earthquakes", {
        type: "geojson",
        data:
          props?.coordinates != undefined
            ? props?.coordinates
            : props?.carriersList?.data,
        cluster: false,
        clusterMaxZoom: 14,
        clusterRadius: 50,
      });

      const initialCenter =
        props?.dash === "1" ? [-97.018, 38.85] : [-97.048, 38.485];
      const initialZoom = props?.dash === "1" ? 2.0222232 : 3.0222;

      map.setCenter(initialCenter);
      map.setZoom(initialZoom);
      const mapContainer = mapContainerRef.current;
      if (mapContainer) {
        mapContainer.addEventListener(
          "wheel",
          (e: { preventDefault: () => void; deltaY: any }) => {
            e.preventDefault();
          },
        );
      }

      map.addSource("states", {
        type: "geojson",
        data: "https://docs.mapbox.com/mapbox-gl-js/assets/us_states.geojson",
      });
      map.on("load", () => {
        // Add a custom vector tileset source. The tileset used in
        // this example contains a feature for every county in the U.S.
        // Each county contains four properties. For example:
        // {
        //     COUNTY: "Uintah County",
        //     FIPS: 49047,
        //     median-income: 62363,
        //     population: 34576
        // }
        map.addSource("counties", {
          type: "vector",
          url: "mapbox://mapbox.82pkq93d",
        });

        map.addLayer(
          {
            id: "counties",
            type: "fill",
            source: "counties",
            "source-layer": "original",
            paint: {
              "fill-outline-color": "rgba(0,0,0,0.1)",
              "fill-color": "rgba(0,0,0,0.1)",
            },
          },
          // Place polygons under labels, roads and buildings.
          "building",
        );

        map.addLayer(
          {
            id: "counties-highlighted",
            type: "fill",
            source: "counties",
            "source-layer": "original",
            paint: {
              "fill-outline-color": "#484896",
              "fill-color": "#6e599f",
              "fill-opacity": 0.75,
            },
            filter: ["in", "FIPS", ""],
          },
          // Place polygons under labels, roads and buildings.
          "building",
        );

        map.on("click", (e) => {
          // Set `bbox` as 5px reactangle area around clicked point.
          const bbox = [
            [e.point.x - 5, e.point.y - 5],
            [e.point.x + 5, e.point.y + 5],
          ];
          // Find features intersecting the bounding box.
          const selectedFeatures = map.queryRenderedFeatures(bbox, {
            layers: ["counties"],
          });
          const fips = selectedFeatures.map(
            (feature) => feature.properties.FIPS,
          );
          // Set a filter matching selected features by FIPS codes
          // to activate the 'counties-highlighted' layer.
          map.setFilter("counties-highlighted", ["in", "FIPS", ...fips]);
        });
      });
      map.on("click", "clusters", (e) => {
        const features = map.queryRenderedFeatures(e.point, {
          layers: ["clusters"],
        });
        if (features.length > 0) {
          const clusterId = features[0].properties.cluster_id;
          map
            .getSource("earthquakes")
            .getClusterExpansionZoom(clusterId, (err: any, zoom: any) => {
              if (err) return;

              map.easeTo({
                center: features[0].geometry.coordinates,
                zoom: 3,
              });
            });
        }
      });
      const markerCoordinates: any[] = [];

      if (props?.coordinates?.features?.length > 0) {
        props?.coordinates?.features?.forEach(
          (feature: { geometry: { coordinates: any } }) => {
            const coordinates = feature?.geometry?.coordinates;

            const marker = new mapboxgl.Marker()
              .setLngLat(coordinates)
              .addTo(map);

            marker.getElement().addEventListener("click", () => {
              const addressNames = feature.properties.title;

              if (props.cluster) {
                props.getNewAdd(addressNames);
              } else if (zoomPin) {
                markets(encodeURIComponent(addressNames));
              }
            });

            markerCoordinates?.push(coordinates);
          },
        );
        const maxZoomLevel = 5;
        const bounds = new mapboxgl.LngLatBounds();

        markerCoordinates?.forEach((coordinates) => {
          bounds?.extend(coordinates || {});
        });
        map?.fitBounds(bounds, {
          padding: 100,
          maxZoom: maxZoomLevel,
        });
      }

      let hoveredStateId: string | number | null | undefined = null;

      map.addLayer({
        id: "state-fills",
        type: "fill",
        source: "states",
        layout: {},
        paint: {
          "fill-color": "#627BC1",
          "fill-opacity": [
            "case",
            ["boolean", ["feature-state", "hover"], false],
            0.5,
            0.1,
          ],
        },
      });

      map.addLayer({
        id: "state-borders",
        type: "line",
        source: "states",
        layout: {},
        paint: {
          "line-color": "#627BC1",
          "line-width": 0.9999,
        },
      });

      map.on("mousemove", "state-fills", (e) => {
        if (e.features.length > 0) {
          if (hoveredStateId !== null) {
            map.setFeatureState(
              { source: "states", id: hoveredStateId },
              { hover: false },
            );
          }
          hoveredStateId = e.features[0].id;
          map.setFeatureState(
            { source: "states", id: hoveredStateId },
            { hover: true },
          );
        }
      });
      map.on("mouseleave", "state-fills", () => {
        if (hoveredStateId !== null) {
          map.setFeatureState(
            { source: "states", id: hoveredStateId },
            { hover: false },
          );
        }
        hoveredStateId = null;
      });
      if (props?.cluster === true) {
        map.on("click", "state-fills", (e) => {
          if (e?.features?.length > 0) {
            const stateName = e?.features[0]?.properties?.STATE_NAME;
            props?.MapState(stateName);
            props.getNewAdd("");
            if (props?.mapStats === 5) {
              props?.setSelectedMarket("")
              props?.setMarketSectionVisible(true);
              props?.setSelectedTerminal("");
            }
          }
        });
      }

      map?.addLayer({
        id: "cluster-count",
        type: "symbol",
        source: "earthquakes",
        filter: ["has", "point_count"],
        layout: {
          "text-field": "{point_count_abbreviated}",
          "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
          "text-size": 12,
        },
        paint: {
          "text-color": "#ffffff",
        },
      });
      if (!props?.keys || props?.keys === 1) {
        map.addLayer({
          id: "unclustered-point",
          type: "symbol",
          source: "earthquakes",
          filter: ["!", ["has", "point_count"]],
          layout: {
            "icon-image": "custom-icon",
            "icon-size": 0.2,
          },
        });
      }

      map?.addLayer({
        id: "cluster-count",
        type: "symbol",
        source: "earthquakes",
        filter: ["has", "point_count"],
        layout: {
          "text-field": "{point_count_abbreviated}",
          "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
          "text-size": 12,
        },
        paint: {
          "text-color": "#ffffff",
        },
      });
      const markets = (encodedAddressName: string) => {
        const url = `/carriers?market=${encodedAddressName}`;
        window.location.href = url;
        return url;
      };

      let popup: mapboxgl.Popup | null;

      map.on("mouseenter", "unclustered-point", (e) => {
        const coordinates = Object.values(e.lngLat);
        const features = map.queryRenderedFeatures(e.point, {
          layers: props?.coordinates?.data,
        });
        if (!features.length) {
          return;
        }

        if (popup) {
          popup.remove();
        }
        
        popup = new mapboxgl.Popup().setLngLat(coordinates).addTo(map);
        map.on("mouseleave", "unclustered-point", () => {
          if (popup) {
            popup.remove();
          }
        });
        
        map.on("click", "unclustered-point", () => {
      
          const featurese = map.queryRenderedFeatures(e.point, {
            layers: ["unclustered-point"],
          });
          if (!featurese.length) {
            return;
          }

          const feature = features[0];
          const addressNames = feature.properties.title;

          if (props.cluster) {
            if (props?.mapStats === 5) {
              props?.setSelectedTerminal("")

             }

            props.getNewAdd(addressNames);
          } else if (zoomPin) {
            markets(encodeURIComponent(addressNames));
          }
        });
      });

      map.on("mouseenter", "unclustered-point", () => {
        map.getCanvas().style.cursor = "pointer";
      });
      map.on("mouseleave", "unclustered-point", () => {
        map.getCanvas().style.cursor = "";
      });
    });
    const coordinatesAndTitles = props?.carriersList?.data?.features?.map(
      (feature) => ({
        coordinates: feature.geometry.coordinates,
        title: feature.properties.title,
      }),
    );

    map.addControl(new mapboxgl.NavigationControl());
    let createdPopups: mapboxgl.Popup[] = [];

    map.on("zoom", () => {
      const currentZoom = map.getZoom();
      const targetZoom = 5.3;

      if (currentZoom >= targetZoom) {
        createdPopups.forEach((popup) => {
          popup.remove();
        });
        createdPopups = [];

        coordinatesAndTitles?.forEach((item: any) => {
          const popup = new mapboxgl.Popup({
            closeOnClick: false,
            className: "transparent-popup",
            maxWidth: "200px",
          })
            .setLngLat(item?.coordinates)
            .setHTML(
              `<div class="transparent-popup-content">${item.title}</div>`,
            )
            .addTo(map);

          createdPopups.push(popup);
        });
      } else {
        createdPopups?.forEach((popup) => {
          popup.remove();
        });
        createdPopups = [];
      }
    });

    map.doubleClickZoom.disable();

    if (!props?.coordinates) {
      // map.dragPan.disable()
    }
  }, [
    props?.coordinates,
    props?.carriersList?.data,
    props?.updatedCordinates?.data,
    props.cluster,
  ]);

  return (
    <div ref={mapContainerRef} style={{ width: "100%", height: "400px" }} />
  );
};

export default Map;
