"use client"

import { useParams } from "next/dist/client/components/navigation"
import { memo, useCallback } from "react"
import { useIntl } from "react-intl"

import { selectRate } from "@/constants/routes/hotelReservation"
import { useHotelsMapStore } from "@/stores/hotels-map"

import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
import HotelLogo from "@/components/Icons/Logos"
import ImageGallery from "@/components/ImageGallery"
import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { mapApiImagesToGalleryImages } from "@/utils/imageGallery"
import { getSingleDecimal } from "@/utils/numberFormatting"

import ReadMore from "../ReadMore"
import TripAdvisorChip from "../TripAdvisorChip"
import HotelPriceCard from "./HotelPriceCard"
import NoPriceAvailableCard from "./NoPriceAvailableCard"
import { hotelCardVariants } from "./variants"

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

import { HotelCardListingTypeEnum } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import type { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps"
import type { Lang } from "@/constants/languages"

function HotelCard({
  hotel,
  isUserLoggedIn,
  state = "default",
  type = HotelCardListingTypeEnum.PageListing,
}: HotelCardProps) {
  const params = useParams()
  const lang = params.lang as Lang
  const intl = useIntl()
  const { setActiveHotelPin, setActiveHotelCard } = useHotelsMapStore()

  const { hotelData } = hotel
  const { price } = hotel

  const handleMouseEnter = useCallback(() => {
    if (hotelData) {
      setActiveHotelPin(hotelData.name)
    }
  }, [setActiveHotelPin, hotelData])

  const handleMouseLeave = useCallback(() => {
    if (hotelData) {
      setActiveHotelPin(null)
      setActiveHotelCard(null)
    }
  }, [setActiveHotelPin, hotelData, setActiveHotelCard])

  if (!hotel || !hotelData) return null

  const amenities = hotelData.detailedFacilities.slice(0, 5)

  const classNames = hotelCardVariants({
    type,
    state,
  })

  const addressStr = `${hotelData.address.streetAddress}, ${hotelData.address.city}`
  const galleryImages = mapApiImagesToGalleryImages(
    hotelData.galleryImages || []
  )

  return (
    <article
      className={classNames}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      <div>
        <div className={styles.imageContainer}>
          <ImageGallery title={hotelData.name} images={galleryImages} fill />
          {hotelData.ratings?.tripAdvisor && (
            <TripAdvisorChip rating={hotelData.ratings.tripAdvisor.rating} />
          )}
        </div>
      </div>
      <div className={styles.hotelContent}>
        <section className={styles.hotelInformation}>
          <div className={styles.titleContainer}>
            <HotelLogo
              hotelId={hotelData.operaId}
              hotelType={hotelData.hotelType}
            />
            <Subtitle textTransform="capitalize" color="uiTextHighContrast">
              {hotelData.name}
            </Subtitle>
            <div className={styles.addressContainer}>
              <address className={styles.address}>
                <Caption color="uiTextPlaceholder">{addressStr}</Caption>
              </address>
              <address className={styles.addressMobile}>
                <Caption color="burgundy" type="underline" asChild>
                  <Link
                    href={`https://www.google.com/maps/dir/?api=1&destination=${hotelData.location.latitude},${hotelData.location.longitude}`}
                    target="_blank"
                    aria-label={intl.formatMessage({
                      id: "Driving directions",
                    })}
                    title={intl.formatMessage({
                      id: "Driving directions",
                    })}
                    color="burgundy"
                    size="small"
                  >
                    {addressStr}
                  </Link>
                </Caption>
              </address>
              <div>
                <Divider variant="vertical" color="subtle" />
              </div>
              <Caption color="uiTextPlaceholder">
                {intl.formatMessage(
                  { id: "{number} km to city center" },
                  {
                    number: getSingleDecimal(
                      hotelData.location.distanceToCentre / 1000
                    ),
                  }
                )}
              </Caption>
            </div>
          </div>
          <Body className={styles.hotelDescription}>
            {hotelData.hotelContent.texts.descriptions.short}
          </Body>
          <div className={styles.facilities}>
            {amenities.map((facility) => {
              const IconComponent = mapFacilityToIcon(facility.id)
              return (
                <div className={styles.facilitiesItem} key={facility.id}>
                  {IconComponent && <IconComponent color="grey80" />}
                  <Caption color="uiTextMediumContrast">
                    {facility.name}
                  </Caption>
                </div>
              )
            })}
          </div>
          <ReadMore
            label={intl.formatMessage({ id: "See hotel details" })}
            hotelId={hotelData.operaId}
            hotel={hotelData}
            showCTA={true}
          />
        </section>
        <div className={styles.prices}>
          {!price ? (
            <NoPriceAvailableCard />
          ) : (
            <>
              {!isUserLoggedIn && price.public && (
                <HotelPriceCard productTypePrices={price.public} />
              )}
              {price.member && (
                <HotelPriceCard
                  productTypePrices={price.member}
                  isMemberPrice
                />
              )}
              <Button
                asChild
                theme="base"
                intent="primary"
                size="small"
                className={styles.button}
              >
                <Link
                  href={`${selectRate(lang)}?hotel=${hotel.hotelData.operaId}`}
                  color="none"
                  keepSearchParams
                >
                  {intl.formatMessage({ id: "See rooms" })}
                </Link>
              </Button>
            </>
          )}
        </div>
      </div>
    </article>
  )
}

export default memo(HotelCard)
