"use client"

import { Map, type MapProps, useMap } from "@vis.gl/react-google-maps"
import { useEffect, useState } from "react"
import { useIntl } from "react-intl"

import { IconButton } from "@scandic-hotels/design-system/IconButton"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"

import {
  DEFAULT_ZOOM,
  MAP_RESTRICTIONS,
  MAX_ZOOM,
  MIN_ZOOM,
} from "@/constants/map"

import { useZoomControls } from "@/hooks/maps/useZoomControls"

import HotelListingMapContent from "./HotelListingMapContent"
import PoiMapMarkers from "./PoiMapMarkers"

import styles from "./interactiveMap.module.css"

import type { InteractiveMapProps } from "@/types/components/hotelPage/map/interactiveMap"

export default function InteractiveMap({
  coordinates,
  pointsOfInterest,
  activePoi,
  hotelPins,
  mapId,
  closeButton,
  markerInfo,
  fitBounds = true,
  onTilesLoaded,
  onActivePoiChange,
}: InteractiveMapProps) {
  const intl = useIntl()
  const map = useMap()
  const [hasInitializedBounds, setHasInitializedBounds] = useState(false)
  const { zoomIn, zoomOut, isMaxZoom, isMinZoom } = useZoomControls()

  const mapOptions: MapProps = {
    defaultZoom: DEFAULT_ZOOM,
    minZoom: MIN_ZOOM,
    maxZoom: MAX_ZOOM,
    defaultCenter: coordinates,
    disableDefaultUI: true,
    clickableIcons: false,
    mapId,
    gestureHandling: "greedy",
    restriction: MAP_RESTRICTIONS,
  }

  useEffect(() => {
    if (map && hotelPins?.length && !hasInitializedBounds) {
      if (fitBounds) {
        const bounds = new google.maps.LatLngBounds()
        hotelPins.forEach((marker) => {
          bounds.extend(marker.coordinates)
        })
        map.fitBounds(bounds, 100)
      }
      setHasInitializedBounds(true)
    }
  }, [map, fitBounds, hotelPins, hasInitializedBounds])

  return (
    <div className={styles.mapContainer}>
      <Map {...mapOptions} onTilesLoaded={onTilesLoaded}>
        {hotelPins && <HotelListingMapContent hotelPins={hotelPins} />}
        {pointsOfInterest && markerInfo && (
          <PoiMapMarkers
            coordinates={coordinates}
            pointsOfInterest={pointsOfInterest}
            onActivePoiChange={onActivePoiChange}
            activePoi={activePoi}
            markerInfo={markerInfo}
          />
        )}
      </Map>
      <div className={styles.ctaButtons}>
        {closeButton}
        <div className={styles.zoomButtons}>
          <IconButton
            theme="Inverted"
            style="Elevated"
            className={styles.zoomButton}
            onClick={zoomOut}
            aria-label={intl.formatMessage({
              defaultMessage: "Zoom out",
            })}
            isDisabled={isMinZoom}
          >
            <MaterialIcon icon="remove" color="CurrentColor" />
          </IconButton>

          <IconButton
            theme="Inverted"
            style="Elevated"
            className={styles.zoomButton}
            onClick={zoomIn}
            aria-label={intl.formatMessage({
              defaultMessage: "Zoom in",
            })}
            isDisabled={isMaxZoom}
          >
            <MaterialIcon icon="add" color="CurrentColor" />
          </IconButton>
        </div>
      </div>
    </div>
  )
}
