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

import { useHotelFilterStore } from "@/stores/hotel-filters"

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

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

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

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

export default function HotelCardListing({
  hotelData,
  type = HotelCardListingTypeEnum.PageListing,
  activeCard,
  onHotelCardHover,
}: HotelCardListingProps) {
  const searchParams = useSearchParams()
  const activeFilters = useHotelFilterStore((state) => state.activeFilters)
  const setResultCount = useHotelFilterStore((state) => state.setResultCount)
  const [showBackToTop, setShowBackToTop] = useState<boolean>(false)
  const intl = useIntl()

  const sortBy = useMemo(
    () => searchParams.get("sort") ?? DEFAULT_SORT,
    [searchParams]
  )

  const sortedHotels = useMemo(() => {
    switch (sortBy) {
      case SortOrder.Name:
        return [...hotelData].sort((a, b) =>
          a.hotelData.name.localeCompare(b.hotelData.name)
        )
      case SortOrder.TripAdvisorRating:
        return [...hotelData].sort(
          (a, b) =>
            (b.hotelData.ratings?.tripAdvisor.rating ?? 0) -
            (a.hotelData.ratings?.tripAdvisor.rating ?? 0)
        )
      case SortOrder.Price:
        const getPricePerNight = (hotel: HotelData): number => {
          return (
            hotel.price?.member?.localPrice?.pricePerNight ??
            hotel.price?.public?.localPrice?.pricePerNight ??
            Infinity
          )
        }
        return [...hotelData].sort(
          (a, b) => getPricePerNight(a) - getPricePerNight(b)
        )
      case SortOrder.Distance:
      default:
        return [...hotelData].sort(
          (a, b) =>
            a.hotelData.location.distanceToCentre -
            b.hotelData.location.distanceToCentre
        )
    }
  }, [hotelData, sortBy])

  const hotels = useMemo(() => {
    if (activeFilters.length === 0) {
      return sortedHotels
    }

    const filteredHotels = sortedHotels.filter((hotel) =>
      activeFilters.every((appliedFilterId) =>
        hotel.hotelData.detailedFacilities.some(
          (facility) => facility.id.toString() === appliedFilterId
        )
      )
    )

    return filteredHotels
  }, [activeFilters, sortedHotels])

  useEffect(() => {
    const handleScroll = () => {
      const hasScrolledPast = window.scrollY > 490
      setShowBackToTop(hasScrolledPast)
    }

    window.addEventListener("scroll", handleScroll, { passive: true })
    return () => window.removeEventListener("scroll", handleScroll)
  }, [])

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

  function scrollToTop() {
    window.scrollTo({ top: 0, behavior: "smooth" })
  }

  return (
    <section className={styles.hotelCards}>
      {hotels?.length ? (
        hotels.map((hotel) => (
          <div
            key={hotel.hotelData.operaId}
            data-active={hotel.hotelData.name === activeCard ? "true" : "false"}
          >
            <HotelCard
              hotel={hotel}
              type={type}
              state={hotel.hotelData.name === activeCard ? "active" : "default"}
              onHotelCardHover={onHotelCardHover}
            />
          </div>
        ))
      ) : activeFilters ? (
        <Alert
          type={AlertTypeEnum.Info}
          heading={intl.formatMessage({ id: "filters.nohotel.heading" })}
          text={intl.formatMessage({ id: "filters.nohotel.text" })}
        />
      ) : null}
      {showBackToTop && (
        <BackToTopButton position="right" onClick={scrollToTop} />
      )}
    </section>
  )
}
