/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */

import { Map as Maplibre, MapEventType, Popup } from 'maplibre-gl';
import React, { memo, useEffect, Fragment } from 'react';
import {
  createPopup,
  getPopupLocation,
  isTooltipEnabledLayer,
  isTooltipEnabledOnHover,
} from './create_tooltip';
import { MapLayerSpecification } from '../../model/mapLayerType';

interface Props {
  map: Maplibre;
  layers: MapLayerSpecification[];
}

export const DisplayFeatures = memo(({ map, layers }: Props) => {
  useEffect(() => {
    let clickPopup: Popup | null = null;
    let hoverPopup: Popup | null = null;

    // We don't want to show layer information in the popup for the map tile layer
    const tooltipEnabledLayers = layers.filter(isTooltipEnabledLayer);

    function onClickMap(e: MapEventType['click']) {
      // remove previous popup
      clickPopup?.remove();

      const features = map.queryRenderedFeatures(e.point);
      if (features && map) {
        // don't show tooltip from labels
        if (features.length === 1 && features[0].layer?.type === 'symbol') {
          return;
        }
        clickPopup = createPopup({ features, layers: tooltipEnabledLayers });
        clickPopup?.setLngLat(getPopupLocation(features[0].geometry, e.lngLat)).addTo(map);
      }
    }

    function onMouseMoveMap(e: MapEventType['mousemove']) {
      // remove previous popup
      hoverPopup?.remove();

      const tooltipEnabledLayersOnHover = layers.filter(isTooltipEnabledOnHover);
      const features = map.queryRenderedFeatures(e.point);
      if (features && map) {
        // don't show tooltip from labels
        if (features.length === 1 && features[0].layer?.type === 'symbol') {
          return;
        }
        hoverPopup = createPopup({
          features,
          layers: tooltipEnabledLayersOnHover,
          // enable close button to avoid occasional dangling tooltip that is not cleared during mouse leave action
          showCloseButton: true,
          showPagination: false,
          showLayerSelection: false,
        });
        hoverPopup?.setLngLat(getPopupLocation(features[0].geometry, e.lngLat)).addTo(map);
      }
    }

    if (map) {
      map.on('click', onClickMap);
      // reset cursor to default when user is no longer hovering over a clickable feature
      map.on('mouseleave', () => {
        map.getCanvas().style.cursor = '';
        hoverPopup?.remove();
      });
      map.on('mouseenter', () => {
        map.getCanvas().style.cursor = 'pointer';
      });
      // add tooltip when users mouse move over a point
      map.on('mousemove', onMouseMoveMap);
    }

    return () => {
      if (map) {
        map.off('click', onClickMap);
        map.off('mousemove', onMouseMoveMap);
      }
    };
  }, [layers]);

  return <Fragment />;
});
