"use client"
import { useSearchParams } from "next/navigation"
import { useSession } from "next-auth/react"
import { useEffect, useMemo, useRef } 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 { isValidClientSession } from "@/utils/clientSession"

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"
import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"

export default function HotelCardListing({
  hotelData,
  type = HotelCardListingTypeEnum.PageListing,
}: HotelCardListingProps) {
  const { data: session } = useSession()
  const isUserLoggedIn = isValidClientSession(session)
  const searchParams = useSearchParams()
  const activeFilters = useHotelFilterStore((state) => state.activeFilters)
  const setResultCount = useHotelFilterStore((state) => state.setResultCount)
  const intl = useIntl()
  const { activeHotel } = useHotelsMapStore()
  const { showBackToTop, scrollToTop } = useScrollToTop({ threshold: 490 })
  const activeCardRef = useRef<HTMLDivElement | null>(null)

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

  const bookingCode = searchParams.get("bookingCode")
  // Special rates (corporate cheque, voucher) will not show regular rate hotels availability
  const isSpecialRate = bookingCode
    ? hotelData.find(
        (hotel) =>
          hotel.availability.productType?.bonusCheque ||
          hotel.availability.productType?.voucher
      )
    : false
  const activeCodeFilter = useBookingCodeFilterStore(
    (state) => state.activeCodeFilter
  )
  const isBookingCodeRateAvailable =
    bookingCode && !isSpecialRate
      ? hotelData.some((hotel) => hotel.availability.bookingCode)
      : false
  const showOnlyBookingCodeRates =
    isBookingCodeRateAvailable &&
    activeCodeFilter === BookingCodeFilterEnum.Discounted

  const hotels = useMemo(() => {
    const sortedHotels = getSortedHotels({
      hotels: hotelData,
      sortBy,
      bookingCode: isSpecialRate ? null : bookingCode,
    })

    const updatedHotelsList = showOnlyBookingCodeRates
      ? sortedHotels.filter((hotel) => hotel.availability.bookingCode)
      : sortedHotels

    if (!activeFilters.length) {
      return updatedHotelsList
    }

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

  useEffect(() => {
    if (activeCardRef.current && type === HotelCardListingTypeEnum.MapListing) {
      activeCardRef.current.scrollIntoView({
        behavior: "smooth",
        block: "nearest",
        inline: "center",
      })
    }
  }, [activeHotel, type])

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

  function isHotelActiveInMapView(hotelName: string): boolean {
    return (
      hotelName === activeHotel && type === HotelCardListingTypeEnum.MapListing
    )
  }

  return (
    <section className={styles.hotelCards}>
      {hotels?.length
        ? hotels.map((hotel) => (
            <div
              key={hotel.hotel.operaId}
              ref={
                isHotelActiveInMapView(hotel.hotel.name) ? activeCardRef : null
              }
              data-active={
                isHotelActiveInMapView(hotel.hotel.name) ? "true" : "false"
              }
            >
              <HotelCard
                hotelData={hotel}
                isUserLoggedIn={isUserLoggedIn}
                state={
                  isHotelActiveInMapView(hotel.hotel.name)
                    ? "active"
                    : "default"
                }
                type={type}
                bookingCode={bookingCode}
              />
            </div>
          ))
        : null}
      {!hotels?.length && activeFilters ? (
        <Alert
          type={AlertTypeEnum.Info}
          heading={intl.formatMessage({
            defaultMessage: "No hotels match your filters",
          })}
          text={intl.formatMessage({
            defaultMessage:
              "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>
  )
}
