"use client"
import { useSearchParams } from "next/navigation"
import { useSession } from "next-auth/react"
import { useEffect, useMemo } from "react"
import { useIntl } from "react-intl"

import { useBookingCodeFilterStore } from "@/stores/bookingCode-filter"
import { useHotelFilterStore } from "@/stores/hotel-filters"
import { useHotelsMapStore } from "@/stores/hotels-map"

import Alert from "@/components/TempDesignSystem/Alert"
import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton"
import { useScrollToTop } from "@/hooks/useScrollToTop"

import HotelCard from "../HotelCard"
import { DEFAULT_SORT } from "../SelectHotel/HotelSorter"
import { getSortedHotels } from "./utils"

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

import {
  type HotelCardListingProps,
  HotelCardListingTypeEnum,
} from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import { AlertTypeEnum } from "@/types/enums/alert"

export default function HotelCardListing({
  hotelData,
  type = HotelCardListingTypeEnum.PageListing,
}: HotelCardListingProps) {
  const { data: session } = useSession()
  const isUserLoggedIn = !!session
  const searchParams = useSearchParams()
  const activeFilters = useHotelFilterStore((state) => state.activeFilters)
  const setResultCount = useHotelFilterStore((state) => state.setResultCount)
  const intl = useIntl()
  const { activeHotelCard } = useHotelsMapStore()
  const { showBackToTop, scrollToTop } = useScrollToTop({ threshold: 490 })

  const sortBy = searchParams.get("sort") ?? DEFAULT_SORT

  const bookingCode = searchParams.get("bookingCode")
  const activeCodeFilter = useBookingCodeFilterStore(
    (state) => state.activeCodeFilter
  )

  const sortedHotels = useMemo(() => {
    if (!hotelData) return []
    return getSortedHotels({ hotels: hotelData, sortBy, bookingCode })
  }, [hotelData, sortBy, bookingCode])

  const hotels = useMemo(() => {
    const updatedHotelsList = bookingCode
      ? sortedHotels.filter(
          (hotel) =>
            !hotel.price ||
            activeCodeFilter === "all" ||
            (activeCodeFilter === "discounted" &&
              hotel.price?.public?.rateType?.toLowerCase() !== "regular") ||
            activeCodeFilter === hotel.price?.public?.rateType?.toLowerCase()
        )
      : sortedHotels

    if (activeFilters.length === 0) return updatedHotelsList

    return updatedHotelsList.filter((hotel) =>
      activeFilters.every((appliedFilterId) =>
        hotel.hotelData.detailedFacilities.some(
          (facility) => facility.id.toString() === appliedFilterId
        )
      )
    )
  }, [activeFilters, sortedHotels, bookingCode, activeCodeFilter])

  useEffect(() => {
    setResultCount(hotels?.length ?? 0)
  }, [hotels, setResultCount])

  return (
    <section className={styles.hotelCards}>
      {hotels?.length ? (
        hotels.map((hotel) => (
          <div
            key={hotel.hotelData.operaId}
            data-active={
              hotel.hotelData.name === activeHotelCard ? "true" : "false"
            }
          >
            <HotelCard
              hotel={hotel}
              isUserLoggedIn={isUserLoggedIn}
              state={
                hotel.hotelData.name === activeHotelCard ? "active" : "default"
              }
              type={type}
              bookingCode={bookingCode}
            />
          </div>
        ))
      ) : activeFilters ? (
        <Alert
          type={AlertTypeEnum.Info}
          heading={intl.formatMessage({ id: "No hotels match your filters" })}
          text={intl.formatMessage({
            id: "It looks like no hotels match your filters. Try adjusting your search to find the perfect stay.",
          })}
        />
      ) : null}
      {showBackToTop && (
        <BackToTopButton position="right" onClick={scrollToTop} />
      )}
    </section>
  )
}
