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

import { selectHotel } from "@/constants/routes/hotelReservation"
import { useHotelFilterStore } from "@/stores/hotel-filters"

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

import FilterAndSortModal from "../FilterAndSortModal"
import HotelListing from "./HotelListing"

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

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

export default function SelectHotelMap({
  apiKey,
  hotelPins,
  mapId,
  hotels,
  filterList,
  cityCoordinates,
}: SelectHotelMapProps) {
  const searchParams = useSearchParams()

  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 listingContainerRef = useRef<HTMLDivElement | null>(null)
  const activeFilters = useHotelFilterStore((state) => state.activeFilters)

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

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

  useEffect(() => {
    if (listingContainerRef.current) {
      const activeElement =
        listingContainerRef.current.querySelector(`[data-active="true"]`)
      if (activeElement) {
        activeElement.scrollIntoView({ behavior: "smooth", block: "nearest" })
      }
    }
  }, [activeHotelPin])

  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" })
  }

  const filteredHotelPins = useMemo(
    () =>
      hotelPins.filter((hotel) =>
        activeFilters.every((filterId) =>
          hotel.facilityIds.includes(Number(filterId))
        )
      ),
    [activeFilters, hotelPins]
  )

  const closeButton = (
    <Button
      intent="inverted"
      size="small"
      theme="base"
      className={styles.closeButton}
      asChild
    >
      <Link href={selectHotel(lang)} keepSearchParams>
        <CloseIcon color="burgundy" />
        {intl.formatMessage({ id: "Close the map" })}
      </Link>
    </Button>
  )
  return (
    <APIProvider apiKey={apiKey}>
      <div className={styles.container}>
        <div className={styles.listingContainer} ref={listingContainerRef}>
          <div className={styles.filterContainer}>
            <Button
              intent="text"
              size="small"
              variant="icon"
              wrapping
              className={styles.filterContainerCloseButton}
              asChild
            >
              <Link href={selectHotel(lang)} keepSearchParams>
                <CloseLargeIcon />
              </Link>
            </Button>
            <FilterAndSortModal filters={filterList} />
          </div>
          <HotelListing
            hotels={hotels}
            activeHotelPin={activeHotelPin}
            setActiveHotelPin={setActiveHotelPin}
          />
          {showBackToTop && (
            <BackToTopButton position="left" onClick={scrollToTop} />
          )}
        </div>
        <InteractiveMap
          closeButton={closeButton}
          coordinates={coordinates}
          hotelPins={filteredHotelPins}
          activeHotelPin={activeHotelPin}
          onActiveHotelPinChange={setActiveHotelPin}
          mapId={mapId}
        />
      </div>
    </APIProvider>
  )
}
