"use client"

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

import { dt } from "@/lib/dt"

import { PriceTagIcon } from "@/components/Icons"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"

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

import type { Price } from "@/types/components/hotelReservation/price"
import { CurrencyEnum } from "@/types/enums/currency"
import type { RoomState } from "@/types/stores/enter-details"

function Row({
  label,
  value,
  bold,
}: {
  label: string
  value: string
  bold?: boolean
}) {
  return (
    <tr className={styles.row}>
      <td>
        <Caption type={bold ? "bold" : undefined}>{label}</Caption>
      </td>
      <td className={styles.price}>
        <Caption type={bold ? "bold" : undefined}>{value}</Caption>
      </td>
    </tr>
  )
}

function TableSection({ children }: React.PropsWithChildren) {
  return <tbody className={styles.tableSection}>{children}</tbody>
}

function TableSectionHeader({
  title,
  subtitle,
}: {
  title: string
  subtitle?: string
}) {
  return (
    <tr>
      <th colSpan={2}>
        <Body>{title}</Body>
        {subtitle ? <Body>{subtitle}</Body> : null}
      </th>
    </tr>
  )
}

export type Room = Pick<
  RoomState["room"],
  | "adults"
  | "bedType"
  | "breakfast"
  | "childrenInRoom"
  | "roomFeatures"
  | "roomRate"
  | "roomType"
> & {
  guest?: RoomState["room"]["guest"]
}

export interface PriceDetailsTableProps {
  bookingCode?: string
  fromDate: string
  isMember: boolean
  rooms: Room[]
  toDate: string
  totalPrice: Price
  vat: number
}

export default function PriceDetailsTable({
  bookingCode,
  fromDate,
  isMember,
  rooms,
  toDate,
  totalPrice,
  vat,
}: PriceDetailsTableProps) {
  const intl = useIntl()
  const lang = useLang()

  const diff = dt(toDate).diff(fromDate, "days")
  const nights = intl.formatMessage(
    { id: "{totalNights, plural, one {# night} other {# nights}}" },
    { totalNights: diff }
  )
  const vatPercentage = vat / 100
  const vatAmount = totalPrice.local.price * vatPercentage

  const priceExclVat = totalPrice.local.price - vatAmount

  const duration = ` ${dt(fromDate).locale(lang).format("ddd, D MMM")}
          -
          ${dt(toDate).locale(lang).format("ddd, D MMM")} (${nights})`
  return (
    <table className={styles.priceDetailsTable}>
      {rooms.map((room, idx) => {
        const getMemberRate =
          room.guest?.join ||
          room.guest?.membershipNo ||
          (idx === 0 && isMember)
        const price =
          getMemberRate && room.roomRate.memberRate
            ? room.roomRate.memberRate
            : room.roomRate.publicRate
        const voucherPrice = room.roomRate.voucherRate
        const chequePrice = room.roomRate.chequeRate
        if (!price) {
          return null
        }
        return (
          <Fragment key={idx}>
            <TableSection>
              {rooms.length > 1 && (
                <Body textTransform="bold">
                  {intl.formatMessage({ id: "Room" })} {idx + 1}
                </Body>
              )}
              <TableSectionHeader title={room.roomType} subtitle={duration} />
              {price && (
                <>
                  <Row
                    label={intl.formatMessage({
                      id: "Average price per night",
                    })}
                    value={formatPrice(
                      intl,
                      price.localPrice.pricePerNight,
                      price.localPrice.currency
                    )}
                  />
                  {room.roomFeatures
                    ? room.roomFeatures.map((feature) => (
                        <Row
                          key={feature.code}
                          label={feature.description}
                          value={formatPrice(
                            intl,
                            +feature.localPrice.totalPrice,
                            feature.localPrice.currency
                          )}
                        />
                      ))
                    : null}
                  {room.bedType ? (
                    <Row
                      label={room.bedType.description}
                      value={formatPrice(intl, 0, price.localPrice.currency)}
                    />
                  ) : null}
                  <Row
                    bold
                    label={intl.formatMessage({ id: "Room charge" })}
                    value={formatPrice(
                      intl,
                      price.localPrice.pricePerStay,
                      price.localPrice.currency
                    )}
                  />
                </>
              )}
              {voucherPrice && (
                <Row
                  bold
                  label={intl.formatMessage({ id: "Room charge" })}
                  value={formatPrice(
                    intl,
                    voucherPrice.numberOfVouchers,
                    CurrencyEnum.Voucher
                  )}
                />
              )}
              {chequePrice && (
                <Row
                  bold
                  label={intl.formatMessage({ id: "Room charge" })}
                  value={formatPrice(
                    intl,
                    chequePrice.localPrice.numberOfBonusCheques,
                    CurrencyEnum.CC,
                    chequePrice.localPrice.additionalPricePerStay,
                    chequePrice.localPrice.currency
                  )}
                />
              )}
            </TableSection>

            {room.breakfast ? (
              <TableSection>
                <Row
                  label={intl.formatMessage(
                    {
                      id: "Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}",
                    },
                    { totalAdults: room.adults, totalBreakfasts: diff }
                  )}
                  value={formatPrice(
                    intl,
                    room.breakfast.localPrice.price * room.adults,
                    room.breakfast.localPrice.currency
                  )}
                />
                {room.childrenInRoom?.length ? (
                  <Row
                    label={intl.formatMessage(
                      {
                        id: "Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}",
                      },
                      {
                        totalChildren: room.childrenInRoom.length,
                        totalBreakfasts: diff,
                      }
                    )}
                    value={formatPrice(
                      intl,
                      0,
                      room.breakfast.localPrice.currency
                    )}
                  />
                ) : null}
                <Row
                  bold
                  label={intl.formatMessage({
                    id: "Breakfast charge",
                  })}
                  value={formatPrice(
                    intl,
                    room.breakfast.localPrice.price * room.adults * diff,
                    room.breakfast.localPrice.currency
                  )}
                />
              </TableSection>
            ) : null}
          </Fragment>
        )
      })}
      <TableSection>
        <TableSectionHeader title={intl.formatMessage({ id: "Total" })} />
        {totalPrice.local.currency !== CurrencyEnum.Voucher &&
        totalPrice.local.currency !== CurrencyEnum.CC ? (
          <>
            <Row
              label={intl.formatMessage({ id: "Price excluding VAT" })}
              value={formatPrice(intl, priceExclVat, totalPrice.local.currency)}
            />
            <Row
              label={intl.formatMessage({ id: "VAT {vat}%" }, { vat })}
              value={formatPrice(intl, vatAmount, totalPrice.local.currency)}
            />
          </>
        ) : null}
        <tr className={styles.row}>
          <td>
            <Body textTransform="bold">
              {intl.formatMessage({ id: "Price including VAT" })}
            </Body>
          </td>
          <td className={styles.price}>
            <Body textTransform="bold">
              {formatPrice(
                intl,
                totalPrice.local.price,
                totalPrice.local.currency,
                totalPrice.local.additionalPrice,
                totalPrice.local.additionalPriceCurrency
              )}
            </Body>
          </td>
        </tr>
        {totalPrice.local.regularPrice && (
          <tr className={styles.row}>
            <td></td>
            <td className={styles.price}>
              <Caption color="uiTextMediumContrast" striked={true}>
                {formatPrice(
                  intl,
                  totalPrice.local.regularPrice,
                  totalPrice.local.currency
                )}
              </Caption>
            </td>
          </tr>
        )}
        {bookingCode && totalPrice.local.regularPrice && (
          <tr className={styles.row}>
            <td>
              <PriceTagIcon />
              {bookingCode}
            </td>
            <td></td>
          </tr>
        )}
      </TableSection>
    </table>
  )
}
