"use client"

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

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

import { MAP_RESTRICTIONS } from "@/constants/map"

import Button from "@/components/TempDesignSystem/Button"

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 [hasFittedBounds, setHasFittedBounds] = useState(false)

  const mapOptions: MapProps = {
    defaultZoom: 14,
    defaultCenter: coordinates,
    disableDefaultUI: true,
    clickableIcons: false,
    mapId,
    gestureHandling: "greedy",
    restriction: MAP_RESTRICTIONS,
  }

  function zoomIn() {
    const currentZoom = map && map.getZoom()
    if (currentZoom) {
      map.setZoom(currentZoom + 1)
    }
  }
  function zoomOut() {
    const currentZoom = map && map.getZoom()
    if (currentZoom) {
      map.setZoom(currentZoom - 1)
    }
  }

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

  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}>
          <Button
            theme="base"
            intent="inverted"
            variant="icon"
            size="small"
            className={styles.zoomButton}
            onClick={zoomOut}
            aria-label={intl.formatMessage({
              defaultMessage: "Zoom in",
            })}
          >
            <MaterialIcon icon="remove" color="CurrentColor" />
          </Button>
          <Button
            theme="base"
            intent="inverted"
            variant="icon"
            size="small"
            className={styles.zoomButton}
            onClick={zoomIn}
            aria-label={intl.formatMessage({
              defaultMessage: "Zoom out",
            })}
          >
            <MaterialIcon icon="add" color="CurrentColor" />
          </Button>
        </div>
      </div>
    </div>
  )
}
