import { cx } from "class-variance-authority"
import { useState } from "react"
import { useFormContext, useWatch } from "react-hook-form"
import { type IntlShape, useIntl } from "react-intl"

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

import {
  AncillaryStepEnum,
  type BreakfastData,
  useAddAncillaryStore,
} from "@/stores/my-stay/add-ancillary-flow"

import { trackAddAncillary } from "@/utils/tracking/myStay"

import { PaymentChoiceEnum } from "../schema"
import PriceDetails from "./PriceDetails"
import { PriceSummary } from "./PriceSummary"

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

import type { SelectedAncillary } from "@/types/components/myPages/myStay/ancillaries"

export default function Summary({ onSubmit }: { onSubmit: () => void }) {
  const intl = useIntl()
  const [isPriceDetailsOpen, setIsPriceDetailsOpen] = useState(false)
  function togglePriceDetails() {
    setIsPriceDetailsOpen((isOpen) => !isOpen)
  }
  const {
    prevStep,
    selectedAncillary,
    isBreakfast,
    breakfastData,
    currentStep,
    selectDeliveryTime,
    selectQuantity,
  } = useAddAncillaryStore((state) => ({
    prevStep: state.prevStep,
    currentStep: state.currentStep,
    selectedAncillary: state.selectedAncillary,
    isBreakfast: state.isBreakfast,
    breakfastData: state.breakfastData,
    selectQuantity: state.selectQuantity,
    selectDeliveryTime: state.selectDeliveryTime,
  }))

  const {
    trigger,
    formState: { isSubmitting, errors },
  } = useFormContext()

  const quantity = useWatch({ name: "quantity" }) as number
  const paymentChoice: PaymentChoiceEnum = useWatch({ name: "paymentChoice" })

  const isConfirmation = currentStep === AncillaryStepEnum.confirmation

  async function handleNextStep() {
    switch (currentStep) {
      case AncillaryStepEnum.selectQuantity: {
        const isValid = await trigger(["quantity", "paymentChoice"])

        if (isValid) {
          const quantityWithCard =
            paymentChoice === PaymentChoiceEnum.Points ? 0 : quantity
          const quantityWithPoints =
            paymentChoice === PaymentChoiceEnum.Points ? quantity : 0
          trackAddAncillary(
            selectedAncillary,
            quantityWithCard,
            quantityWithPoints,
            breakfastData
          )

          selectQuantity()
        }
        break
      }
      case AncillaryStepEnum.selectDelivery: {
        const isValid = await trigger("deliveryTime")
        if (isValid) {
          selectDeliveryTime()
        }
        break
      }
      case AncillaryStepEnum.confirmation: {
        onSubmit()
        break
      }
    }
  }

  if (!selectedAncillary || (!breakfastData && isBreakfast)) {
    return null
  }

  const isSingleItem = !selectedAncillary.requiresQuantity
  const secondaryButtonLabel =
    currentStep === AncillaryStepEnum.selectQuantity
      ? intl.formatMessage({
          id: "common.cancel",
          defaultMessage: "Cancel",
        })
      : intl.formatMessage({
          id: "common.back",
          defaultMessage: "Back",
        })

  function buttonLabel() {
    switch (currentStep) {
      case AncillaryStepEnum.selectQuantity:
        return isSingleItem
          ? intl.formatMessage({
              id: "common.reviewAndConfirm",
              defaultMessage: "Review & Confirm",
            })
          : intl.formatMessage({
              id: "addAncillaryFlowModal.proceedToDelivery",
              defaultMessage: "Proceed to delivery",
            })
      case AncillaryStepEnum.selectDelivery:
        return intl.formatMessage({
          id: "common.reviewAndConfirm",
          defaultMessage: "Review & Confirm",
        })
      case AncillaryStepEnum.confirmation:
        return intl.formatMessage({
          id: "addAncillaryFlowModal.addToBooking",
          defaultMessage: "Add to booking",
        })
    }
  }

  const items = isBreakfast
    ? getBreakfastItems(intl, selectedAncillary, breakfastData)
    : [
        {
          title: selectedAncillary.title,
          totalPrice: selectedAncillary.price.total,
          currency: selectedAncillary.price.currency,
          points: selectedAncillary.points,
          quantity,
        },
      ]

  const totalPrice = isBreakfast
    ? breakfastData!.totalPrice
    : paymentChoice === PaymentChoiceEnum.Card && selectedAncillary
      ? selectedAncillary.price.total * quantity
      : null

  const totalPoints =
    paymentChoice === PaymentChoiceEnum.Points && selectedAncillary?.points
      ? selectedAncillary.points * quantity
      : null

  return (
    <div className={styles.summary}>
      <div
        className={cx({
          [styles.backgroundBox]: isConfirmation || isSingleItem,
        })}
      >
        {(isSingleItem || isConfirmation) && (
          <PriceDetails
            totalPrice={totalPrice}
            totalPoints={totalPoints}
            selectedAncillary={selectedAncillary}
          />
        )}
        {isConfirmation && isPriceDetailsOpen && (
          <PriceSummary
            totalPrice={totalPrice}
            totalPoints={totalPoints}
            items={items}
            paymentChoice={paymentChoice}
          />
        )}
        <div
          className={cx({
            [styles.confirmButtons]: isConfirmation,
          })}
        >
          {isConfirmation && (
            <Button
              type="button"
              size="sm"
              variant="Text"
              onPress={togglePriceDetails}
              className={styles.priceButton}
            >
              {intl.formatMessage({
                id: "commonpriceDetails",
                defaultMessage: "Price details",
              })}
              <MaterialIcon
                icon={
                  isPriceDetailsOpen
                    ? "keyboard_arrow_up"
                    : "keyboard_arrow_down"
                }
                size={20}
                color="CurrentColor"
              />
            </Button>
          )}

          <div className={styles.buttons}>
            <Button
              type="button"
              variant="Text"
              size="sm"
              color="Primary"
              wrapping={false}
              onPress={prevStep}
            >
              {secondaryButtonLabel}
            </Button>
            <Button
              size="sm"
              isDisabled={isSubmitting}
              isPending={isSubmitting}
              onPress={handleNextStep}
              variant={isSingleItem || isConfirmation ? "Primary" : "Secondary"}
            >
              {buttonLabel()}
            </Button>
          </div>
        </div>
      </div>
    </div>
  )
}

function getBreakfastItems(
  intl: IntlShape,
  selectedAncillary: SelectedAncillary,
  breakfastData: BreakfastData | null
) {
  if (!breakfastData) {
    return []
  }

  const items = [
    {
      title: `${selectedAncillary.title} / ${intl.formatMessage({
        id: "common.adult",
        defaultMessage: "adult",
      })}`,
      totalPrice: breakfastData.priceAdult,
      currency: breakfastData.currency,
      quantity: breakfastData.nrOfAdults * breakfastData.nrOfNights,
    },
  ]

  if (breakfastData.nrOfPayingChildren > 0) {
    items.push({
      title: `${selectedAncillary.title} / ${intl.formatMessage({
        id: "common.children",
        defaultMessage: "Children",
      })} 4-12`,
      totalPrice: breakfastData.priceChild,
      currency: breakfastData.currency,
      quantity: breakfastData.nrOfPayingChildren * breakfastData.nrOfNights,
    })
  }

  if (breakfastData.nrOfFreeChildren > 0) {
    items.push({
      title: `${selectedAncillary.title} / ${intl.formatMessage(
        {
          id: "common.childrenUnderAge",
          defaultMessage: "Children under {age}",
        },
        { age: 4 }
      )}`,
      totalPrice: 0,
      currency: breakfastData.currency,
      quantity: breakfastData.nrOfFreeChildren * breakfastData.nrOfNights,
    })
  }

  return items
}
