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

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 { activeHotelCard } = useHotelsMapStore()
  const { showBackToTop, scrollToTop } = useScrollToTop({ threshold: 490 })

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

  const bookingCode = searchParams.get("bookingCode")
  // Special rates (corporate cheque, voucher and reward nights) will not have regular rate hotels availability
  const isSpecialRate = hotelData.find(
    (hotel) =>
      hotel.availability.productType?.bonusCheque ||
      hotel.availability.productType?.voucher ||
      hotel.availability.productType?.redemptions
  )
  const activeCodeFilter = useBookingCodeFilterStore(
    (state) => state.activeCodeFilter
  )

  const hotels = useMemo(() => {
    const sortedHotels = getSortedHotels({
      hotels: hotelData,
      sortBy,
      bookingCode: isSpecialRate ? null : bookingCode,
    })
    const updatedHotelsList =
      bookingCode && !isSpecialRate
        ? sortedHotels.filter(
            (hotel) =>
              !hotel.availability.productType ||
              activeCodeFilter === BookingCodeFilterEnum.All ||
              (activeCodeFilter === BookingCodeFilterEnum.Discounted &&
                hotel.availability.productType.public?.rateType !==
                  RateTypeEnum.Regular &&
                hotel.availability.productType.member?.rateType !==
                  RateTypeEnum.Regular) ||
              (activeCodeFilter === BookingCodeFilterEnum.Regular &&
                (hotel.availability.productType.public?.rateType ===
                  RateTypeEnum.Regular ||
                  hotel.availability.productType.member?.rateType ===
                    RateTypeEnum.Regular))
          )
        : sortedHotels

    if (!activeFilters.length) {
      return updatedHotelsList
    }

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

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

  return (
    <section className={styles.hotelCards}>
      {hotels?.length
        ? hotels.map((hotel) => (
            <div
              key={hotel.hotel.operaId}
              data-active={
                hotel.hotel.name === activeHotelCard ? "true" : "false"
              }
            >
              <HotelCard
                hotelData={hotel}
                isUserLoggedIn={isUserLoggedIn}
                state={
                  hotel.hotel.name === activeHotelCard ? "active" : "default"
                }
                type={type}
                bookingCode={bookingCode}
              />
            </div>
          ))
        : null}
      {!hotels?.length && 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>
  )
}
