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

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

import Accordion from "@/components/TempDesignSystem/Accordion"
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
import Divider from "@/components/TempDesignSystem/Divider"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatPrice } from "@/utils/numberFormatting"

import { getBreakfastPackagesFromAncillaryFlow } from "../../utils/hasBreakfastPackage"
import RemoveButton from "./RemoveButton"

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

import type { AddedAncillariesProps } from "@/types/components/myPages/myStay/ancillaries"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
import type { Room } from "@/types/stores/my-stay"
import type { PackageSchema } from "@/types/trpc/routers/booking/confirmation"

export function AddedAncillaries({
  ancillaries,
  booking,
}: AddedAncillariesProps) {
  const intl = useIntl()

  const addedBreakfastPackages = getBreakfastPackagesFromAncillaryFlow(
    booking.originalPackages
  )

  const addedAncillaries = getAddedAncillaries(booking, addedBreakfastPackages)

  if (addedAncillaries.length === 0) {
    return null
  }

  return (
    <div className={styles.container}>
      <div className={styles.header}>
        <Subtitle>
          {intl.formatMessage({
            defaultMessage: "My Add-on's",
          })}
        </Subtitle>

        {booking.ancillary?.deliveryTime && (
          <div className={styles.deliveryTime}>
            <Body color="baseTextHighContrast" textTransform="bold">
              {intl.formatMessage({
                defaultMessage: "Delivered at:",
              })}
            </Body>
            <Body color="baseTextHighContrast" textTransform="bold">
              {booking.ancillary?.deliveryTime}
            </Body>
          </div>
        )}
      </div>

      {addedAncillaries.map((ancillary) => {
        const ancillaryTitle = `${
          ancillary.code === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
            ? intl.formatMessage({
                defaultMessage: "Breakfast",
              })
            : (ancillaries?.find(
                (a) =>
                  a.id === ancillary.code || a.loyaltyCode === ancillary.code
              )?.title ?? "")
        } X${ancillary.totalUnit}`

        return (
          <Fragment key={ancillary.code}>
            <Accordion className={styles.ancillaryMobile}>
              <AccordionItem
                title={ancillaryTitle}
                icon={
                  <MaterialIcon
                    icon="check_circle"
                    color="Icon/Feedback/Success"
                  />
                }
              >
                <div>
                  {ancillary.comment && (
                    <>
                      <div className={styles.commentMobile}>
                        <Body textTransform="bold">
                          {intl.formatMessage({
                            defaultMessage: "Other requests",
                          })}
                          {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                          {":"}
                        </Body>
                        <Body color="uiTextMediumContrast">
                          {ancillary.comment}
                        </Body>
                      </div>
                    </>
                  )}
                  <div className={styles.paymentMobileWrapper}>
                    <div className={styles.paymentMobile}>
                      <Body>
                        {intl.formatMessage({
                          defaultMessage: "Total",
                        })}
                      </Body>
                      <Body textTransform="bold">
                        {ancillary.currency.toLowerCase() === "points"
                          ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
                            `${ancillary.totalPrice} ${intl.formatMessage({
                              defaultMessage: "Points",
                            })}`
                          : formatPrice(
                              intl,
                              ancillary.totalPrice,
                              ancillary.currency
                            )}
                      </Body>
                    </div>
                  </div>
                </div>

                <div className={styles.footerMobile}>
                  {booking.confirmationNumber && ancillary.code ? (
                    <div className={styles.actions}>
                      <RemoveButton
                        refId={booking.refId}
                        codes={
                          ancillary.code ===
                          BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
                            ? addedBreakfastPackages!.map((p) => p.code)
                            : [ancillary.code]
                        }
                        title={ancillaryTitle}
                        booking={booking}
                        ancillary={ancillary}
                        addedBreakfastPackages={addedBreakfastPackages}
                      />
                    </div>
                  ) : null}
                </div>
              </AccordionItem>
            </Accordion>
            <div className={styles.ancillaryDesktop}>
              <div className={styles.specification}>
                <div className={styles.name}>
                  <MaterialIcon
                    icon="check_circle"
                    color="Icon/Feedback/Success"
                  />
                  <Body textTransform="bold">{ancillaryTitle}</Body>
                </div>
                <div className={styles.payment}>
                  <Body>
                    {intl.formatMessage({
                      defaultMessage: "Total",
                    })}
                  </Body>
                  <Body textTransform="bold">
                    {ancillary.currency.toLowerCase() === "points"
                      ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
                        `${ancillary.totalPrice} ${intl.formatMessage({
                          defaultMessage: "Points",
                        })}`
                      : formatPrice(
                          intl,
                          ancillary.totalPrice,
                          ancillary.currency
                        )}
                  </Body>
                </div>
              </div>

              <Divider color="baseSurfaceSubtleHover" />

              <div className={styles.footer}>
                <div className={styles.comment}>
                  {ancillary.comment && (
                    <>
                      <Body textTransform="bold">
                        {intl.formatMessage({
                          defaultMessage: "Other requests",
                        })}
                        {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                        {":"}
                      </Body>
                      <Body>{ancillary.comment}</Body>
                    </>
                  )}
                </div>
                {booking.confirmationNumber &&
                ancillary.code &&
                booking.canModifyAncillaries ? (
                  <div className={styles.actions}>
                    <RemoveButton
                      refId={booking.refId}
                      codes={
                        ancillary.code ===
                        BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
                          ? addedBreakfastPackages!.map((p) => p.code)
                          : [ancillary.code]
                      }
                      title={ancillaryTitle}
                      booking={booking}
                      ancillary={ancillary}
                      addedBreakfastPackages={addedBreakfastPackages}
                    />
                  </div>
                ) : null}
              </div>
            </div>
          </Fragment>
        )
      })}
    </div>
  )
}

/**
 * All ancillaries that are added to the booking
 *
 * Adding a special ancillary for breakfast, calculated from
 * all breakfast packages that has been added as ancillaries,
 * not in the booking flow.
 */
function getAddedAncillaries(
  booking: Room,
  addedBreakfastPackages: PackageSchema[] | undefined
) {
  if (!addedBreakfastPackages?.length) {
    return booking.ancillaries
  }

  const combinedBreakfastPackageAsAncillary: PackageSchema = {
    code: BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST,
    unitPrice: 0,
    currency: addedBreakfastPackages[0].currency,
    type: addedBreakfastPackages[0].type,
    description: addedBreakfastPackages[0].description,
    comment: addedBreakfastPackages[0].comment,
    totalPrice: addedBreakfastPackages.reduce(
      (acc, curr) => acc + curr.totalPrice,
      0
    ),
    unit: addedBreakfastPackages.reduce((acc, curr) => acc + curr.unit, 0),
    totalUnit: addedBreakfastPackages.reduce(
      (acc, curr) => acc + curr.totalUnit,
      0
    ),
  }

  return [combinedBreakfastPackageAsAncillary, ...booking.ancillaries]
}
