"use client"

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

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

import { useDestinationDataStore } from "@/stores/destination-data"

import DestinationFilterAndSort from "@/components/DestinationFilterAndSort"
import { debounce } from "@/utils/debounce"

import HotelListContent from "./Content"
import HotelListSkeleton from "./HotelListSkeleton"
import { getVisibleHotels } from "./utils"

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

import type { DestinationPagesHotelData } from "@/types/hotel"

export default function HotelList() {
  const intl = useIntl()
  const map = useMap()
  const coreLib = useMapsLibrary("core")
  const [visibleHotels, setVisibleHotels] = useState<
    DestinationPagesHotelData[]
  >([])
  const { activeHotels, isLoading } = useDestinationDataStore((state) => ({
    activeHotels: state.activeHotels,
    isLoading: state.isLoading,
  }))

  const debouncedUpdateVisibleHotels = useMemo(
    () =>
      debounce(() => {
        setVisibleHotels(getVisibleHotels(activeHotels, map))
      }, 500),
    [map, activeHotels]
  )

  useEffect(() => {
    if (!map || !coreLib) {
      return
    }

    function handleBoundsChanged() {
      debouncedUpdateVisibleHotels()
    }

    coreLib.event.addListener(map, "bounds_changed", handleBoundsChanged)
    return () => {
      coreLib.event.clearListeners(map, "bounds_changed")
    }
  }, [map, coreLib, debouncedUpdateVisibleHotels])

  if (isLoading) {
    return <HotelListSkeleton />
  }

  return (
    <div className={styles.hotelListWrapper}>
      <div className={styles.header}>
        <Typography variant="Body/Paragraph/mdRegular">
          <p>
            {intl.formatMessage(
              {
                defaultMessage: "{count} hotels",
              },
              { count: visibleHotels.length }
            )}
          </p>
        </Typography>
        <DestinationFilterAndSort listType="hotel" />
      </div>

      <HotelListContent
        hotelsCount={activeHotels.length}
        visibleHotels={visibleHotels}
      />
    </div>
  )
}
