"use client"
import { APIProvider } from "@vis.gl/react-google-maps"
import { useRouter, useSearchParams } from "next/navigation"
import { useEffect, useState } from "react"
import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"

import { selectHotel } from "@/constants/routes/hotelReservation"

import { CloseIcon, CloseLargeIcon } from "@/components/Icons"
import InteractiveMap from "@/components/Maps/InteractiveMap"
import Button from "@/components/TempDesignSystem/Button"
import useLang from "@/hooks/useLang"

import HotelListing from "./HotelListing"
import { getCentralCoordinates } from "./utils"

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

import { SelectHotelMapProps } from "@/types/components/hotelReservation/selectHotel/map"

export default function SelectHotelMap({
  apiKey,
  hotelPins,
  mapId,
  hotels,
}: SelectHotelMapProps) {
  const searchParams = useSearchParams()
  const router = useRouter()
  const lang = useLang()
  const intl = useIntl()
  const isAboveMobile = useMediaQuery("(min-width: 768px)")
  const [activeHotelPin, setActiveHotelPin] = useState<string | null>(null)
  const [showBackToTop, setShowBackToTop] = useState<boolean>(false)

  const centralCoordinates = getCentralCoordinates(hotelPins)

  const coordinates = isAboveMobile
    ? centralCoordinates
    : { ...centralCoordinates, lat: centralCoordinates.lat - 0.006 }

  const selectHotelParams = new URLSearchParams(searchParams.toString())
  const selectedHotel = selectHotelParams.get("selectedHotel")

  useEffect(() => {
    if (selectedHotel) {
      setActiveHotelPin(selectedHotel)
    }
  }, [selectedHotel])

  useEffect(() => {
    const hotelListingElement = document.querySelector(
      `.${styles.listingContainer}`
    )
    if (!hotelListingElement) return

    const handleScroll = () => {
      const hasScrolledPast = hotelListingElement.scrollTop > 490
      setShowBackToTop(hasScrolledPast)
    }

    hotelListingElement.addEventListener("scroll", handleScroll)
    return () => hotelListingElement.removeEventListener("scroll", handleScroll)
  }, [])

  function scrollToTop() {
    const hotelListingElement = document.querySelector(
      `.${styles.listingContainer}`
    )
    hotelListingElement?.scrollTo({ top: 0, behavior: "smooth" })
  }

  function handlePageRedirect() {
    router.push(`${selectHotel[lang]}?${searchParams.toString()}`)
  }

  const closeButton = (
    <Button
      intent="inverted"
      size="small"
      theme="base"
      className={styles.closeButton}
      onClick={handlePageRedirect}
    >
      <CloseIcon color="burgundy" />
      {intl.formatMessage({ id: "Close the map" })}
    </Button>
  )
  return (
    <APIProvider apiKey={apiKey}>
      <div className={styles.container}>
        <div className={styles.listingContainer}>
          <div className={styles.filterContainer}>
            <Button
              intent="text"
              size="small"
              variant="icon"
              wrapping
              onClick={handlePageRedirect}
              className={styles.filterContainerCloseButton}
            >
              <CloseLargeIcon />
            </Button>
            <span>Filter and sort</span>
            {/* TODO: Add filter and sort button */}
          </div>
          <HotelListing
            hotels={hotels}
            activeHotelPin={activeHotelPin}
            setActiveHotelPin={setActiveHotelPin}
          />
          {showBackToTop && (
            <Button
              intent="inverted"
              size="small"
              theme="base"
              className={styles.backToTopButton}
              onClick={scrollToTop}
            >
              {intl.formatMessage({ id: "Back to top" })}
            </Button>
          )}
        </div>
        <InteractiveMap
          closeButton={closeButton}
          coordinates={coordinates}
          hotelPins={hotelPins}
          activeHotelPin={activeHotelPin}
          onActiveHotelPinChange={setActiveHotelPin}
          mapId={mapId}
        />
      </div>
    </APIProvider>
  )
}
