"use client"

import { useEffect } from "react"
import { useIntl } from "react-intl"

import {
  Discount22Icon,
  MaterialIcon,
} from "@scandic-hotels/design-system/Icons"
import { Typography } from "@scandic-hotels/design-system/Typography"

import { BookingStatusEnum } from "@/constants/booking"
import { dt } from "@/lib/dt"
import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore"
import { useMyStayTotalPriceStore } from "@/stores/my-stay/myStayTotalPrice"

import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider"
import IconChip from "@/components/TempDesignSystem/IconChip"
import Link from "@/components/TempDesignSystem/Link"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { useGuaranteePaymentFailedToast } from "@/hooks/booking/useGuaranteePaymentFailedToast"
import useLang from "@/hooks/useLang"

import ManageStay from "../ManageStay"
import TotalPrice from "../Rooms/TotalPrice"
import { mapRoomDetails } from "../utils/mapRoomDetails"
import ReferenceCardSkeleton from "./ReferenceCardSkeleton"

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

import type { Hotel, Room } from "@/types/hotel"
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
import type { CreditCard } from "@/types/user"

interface ReferenceCardProps {
  booking: BookingConfirmation["booking"]
  hotel: Hotel
  room:
    | (Room & {
        bedType: Room["roomTypes"][number]
      })
    | null
  savedCreditCards: CreditCard[] | null
  refId: string
  isLoggedIn: boolean
}

export function ReferenceCard({
  booking,
  hotel,
  room,
  savedCreditCards,
  refId,
  isLoggedIn,
}: ReferenceCardProps) {
  const intl = useIntl()
  const lang = useLang()
  const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom)
  const linkedReservationRooms = useMyStayRoomDetailsStore(
    (state) => state.linkedReservationRooms
  )
  const addBookedRoom = useMyStayRoomDetailsStore(
    (state) => state.actions.addBookedRoom
  )
  const addRoomPrice = useMyStayTotalPriceStore(
    (state) => state.actions.addRoomPrice
  )

  // Initialize store with server data
  useEffect(() => {
    // Add price and details for booked room (main room or single room)
    addRoomPrice({
      id: booking.confirmationNumber,
      totalPrice:
        booking.reservationStatus === BookingStatusEnum.Cancelled
          ? 0
          : booking.totalPrice,
      currencyCode: booking.currencyCode,
      isMainBooking: true,
      roomPoints: booking.roomPoints,
    })
    addBookedRoom(
      mapRoomDetails({
        booking,
        room,
        roomNumber: 1,
      })
    )
  }, [booking, room, addBookedRoom, addRoomPrice])

  useGuaranteePaymentFailedToast()

  if (!bookedRoom.roomNumber) return <ReferenceCardSkeleton />

  const {
    confirmationNumber,
    cancellationNumber,
    isCancelled,
    bookingCode,
    rateDefinition,
    priceType,
  } = bookedRoom

  const isMultiRoom = bookedRoom.linkedReservations.length > 0

  const directionsUrl = `https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`

  const allRooms = [bookedRoom, ...linkedReservationRooms]

  const adults = allRooms
    .filter((room) => !room.isCancelled)
    .reduce((acc, room) => acc + room.adults, 0)

  const children = allRooms
    .filter((room) => !room.isCancelled)
    .reduce((acc, room) => acc + (room.childrenAges?.length ?? 0), 0)

  const cancelledRooms = allRooms.filter((room) => room.isCancelled).length
  const allRoomsCancelled = allRooms.every((room) => room.isCancelled)

  const adultsMsg = intl.formatMessage(
    { id: "{adults, plural, one {# adult} other {# adults}}" },
    {
      adults: adults,
    }
  )

  const childrenMsg = intl.formatMessage(
    {
      id: "{children, plural, one {# child} other {# children}}",
    },
    {
      children: children,
    }
  )

  const cancelledRoomsMsg = intl.formatMessage(
    { id: "{rooms, plural, one {# room} other {# rooms}}" },
    {
      rooms: cancelledRooms,
    }
  )

  const roomCancelledRoomsMsg = intl.formatMessage({ id: "Room cancelled" })

  const roomsMsg = intl.formatMessage(
    { id: "{rooms, plural, one {# room} other {# rooms}}" },
    {
      rooms: allRooms.filter((room) => !room.isCancelled).length,
    }
  )
  const adultsOnlyMsg = adultsMsg
  const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ")
  const adultsAndRoomsMsg = [adultsMsg, roomsMsg].join(", ")
  const adultsAndChildrenAndRoomsMsg = [adultsMsg, childrenMsg, roomsMsg].join(
    ", "
  )

  return (
    <div className={styles.referenceCard}>
      {!isMultiRoom && (
        <>
          <div className={styles.referenceRow}>
            <Subtitle color="uiTextHighContrast" className={styles.titleMobile}>
              {intl.formatMessage({ id: "Reference" })}
            </Subtitle>
            <Subtitle
              color="uiTextHighContrast"
              className={styles.titleDesktop}
            >
              {isCancelled && !isMultiRoom
                ? intl.formatMessage({ id: "Cancellation number" })
                : intl.formatMessage({ id: "Reference number" })}
            </Subtitle>
            <Subtitle color="uiTextHighContrast">
              {isCancelled && !isMultiRoom
                ? cancellationNumber
                : confirmationNumber}
            </Subtitle>
          </div>

          <Divider color="subtle" className={styles.divider} />
        </>
      )}

      {!allRoomsCancelled && (
        <div className={styles.referenceRow}>
          <Typography variant="Title/Overline/sm">
            <p>{intl.formatMessage({ id: "Guests" })}</p>
          </Typography>
          <Typography variant="Body/Paragraph/mdBold">
            <p>
              {allRooms.length > 1
                ? children > 0
                  ? adultsAndChildrenAndRoomsMsg
                  : adultsAndRoomsMsg
                : children > 0
                  ? adultsAndChildrenMsg
                  : adultsOnlyMsg}
            </p>
          </Typography>
        </div>
      )}
      {allRooms.some((room) => room.isCancelled) && (
        <div className={styles.referenceRow}>
          <Typography variant="Title/Overline/sm">
            <p>{intl.formatMessage({ id: "Cancellation" })}</p>
          </Typography>
          <Typography variant="Body/Paragraph/mdBold">
            <p className={styles.cancelledRooms}>
              {isMultiRoom
                ? `${cancelledRoomsMsg} ${intl.formatMessage({ id: "cancelled" })}`
                : roomCancelledRoomsMsg}
            </p>
          </Typography>
        </div>
      )}
      {!allRoomsCancelled && (
        <>
          <div className={styles.referenceRow}>
            <Typography variant="Title/Overline/sm">
              <p>{intl.formatMessage({ id: "Check-in" })}</p>
            </Typography>
            <Typography variant="Body/Paragraph/mdBold">
              <p>
                {`${dt(booking.checkInDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage({ id: "from" })} ${hotel.hotelFacts.checkin.checkInTime}`}
              </p>
            </Typography>
          </div>
          <div className={styles.referenceRow}>
            <Typography variant="Title/Overline/sm">
              <p>{intl.formatMessage({ id: "Check-out" })}</p>
            </Typography>
            <Typography variant="Body/Paragraph/mdBold">
              <p>
                {`${dt(booking.checkOutDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage({ id: "until" })} ${hotel.hotelFacts.checkin.checkOutTime}`}
              </p>
            </Typography>
          </div>
        </>
      )}
      <Divider color="subtle" className={styles.divider} />
      {booking.guaranteeInfo && !allRoomsCancelled && (
        <>
          <div className={styles.guaranteed}>
            <MaterialIcon
              icon="check_circle"
              color="Icon/Feedback/Success"
              size={20}
            />
            <Typography variant="Body/Supporting text (caption)/smRegular">
              <p className={styles.guaranteedText}>
                <strong>
                  {intl.formatMessage({ id: "Booking guaranteed." })}
                </strong>{" "}
                {intl.formatMessage({
                  id: "Your stay remains available for check-in after 18:00.",
                })}
              </p>
            </Typography>
          </div>
          <Divider color="subtle" className={styles.divider} />
        </>
      )}

      <div className={styles.referenceRow}>
        <Typography variant="Title/Overline/sm">
          <p>{intl.formatMessage({ id: "Total" })}</p>
        </Typography>
        <TotalPrice variant="Title/Subtitle/md" type={priceType} />
      </div>
      {bookingCode && (
        <div className={styles.referenceRow}>
          <Typography variant="Title/Overline/sm">
            <p>{intl.formatMessage({ id: "Booking code" })}</p>
          </Typography>
          <IconChip
            color="blue"
            icon={<Discount22Icon color="Icon/Feedback/Information" />}
          >
            <Typography variant="Body/Supporting text (caption)/smBold">
              <p className={styles.bookingCode}>
                <strong>{intl.formatMessage({ id: "Booking code" })}</strong>:{" "}
                {bookingCode}
              </p>
            </Typography>
          </IconChip>
        </div>
      )}
      <div className={styles.actionArea}>
        <ManageStay
          hotel={hotel}
          savedCreditCards={savedCreditCards}
          refId={refId}
          isLoggedIn={isLoggedIn}
        />
        <Button fullWidth intent="secondary" asChild size="small">
          <Link href={directionsUrl} target="_blank">
            {intl.formatMessage({ id: "Get directions" })}
          </Link>
        </Button>
      </div>
      {isMultiRoom && (
        <Typography variant="Body/Supporting text (caption)/smBold">
          <p className={styles.note}>
            {intl.formatMessage({ id: "Multi-room stay" })}
          </p>
        </Typography>
      )}

      <Typography variant="Body/Supporting text (caption)/smRegular">
        <p
          className={`${styles.note} ${allRoomsCancelled ? styles.cancelledNote : ""}`}
        >
          {rateDefinition.generalTerms.map((term) => (
            <span key={term}>
              {term}
              {term.endsWith(".") ? " " : ". "}
            </span>
          ))}
        </p>
      </Typography>
    </div>
  )
}
