"use client"
import { useSession } from "next-auth/react"
import { useState } from "react"
import { useIntl } from "react-intl"

import { trpc } from "@/lib/trpc/client"
import { useMyStayStore } from "@/stores/my-stay"

import { sumPackages } from "@/components/HotelReservation/utils"
import useLang from "@/hooks/useLang"
import { isValidClientSession } from "@/utils/clientSession"
import { formatPrice } from "@/utils/numberFormatting"

import Confirmation from "./Confirmation"
import Form from "./Form"

import type { ChangeDatesStepsProps } from "@/types/components/hotelReservation/myStay/changeDates"
import { CurrencyEnum } from "@/types/enums/currency"

interface Dates {
  fromDate: string
  toDate: string
}

export default function Steps({ closeModal }: ChangeDatesStepsProps) {
  const { data: session } = useSession()
  const isLoggedIn = isValidClientSession(session)
  const intl = useIntl()
  const lang = useLang()
  const utils = trpc.useUtils()
  const [dates, setDates] = useState<Dates | null>(null)
  const [newPrice, setNewPrice] = useState<string | null>(null)
  const [noAvailability, setNoAvailability] = useState(false)

  const { breakfast, currencyCode, hotelId, packages, room } = useMyStayStore(
    (state) => ({
      breakfast: state.bookedRoom.breakfast,
      currencyCode: state.bookedRoom.currencyCode,
      hotelId: state.bookedRoom.hotelId,
      packages: state.bookedRoom.packages ?? [],
      room: {
        adults: state.bookedRoom.adults,
        bookingCode: state.bookedRoom.bookingCode ?? undefined,
        childrenInRoom: state.bookedRoom.childrenInRoom,
        rateCode: state.bookedRoom.rateDefinition.rateCode,
        roomTypeCode: state.bookedRoom.roomTypeCode,
      },
    })
  )

  async function checkAvailability(fromDate: string, toDate: string) {
    setNoAvailability(false)

    const data = await utils.hotel.availability.myStay.fetch({
      booking: { fromDate, hotelId, room, toDate },
      lang,
    })

    if (!data || !data.selectedRoom || !data.selectedRoom.roomsLeft) {
      setNoAvailability(true)
      return
    }

    setDates({ fromDate, toDate })

    const pkgsSum = sumPackages(packages)
    const extraPrice =
      pkgsSum.price + ((breakfast && breakfast.localPrice.totalPrice) || 0)
    if (isLoggedIn && "member" in data.product && data.product.member) {
      const { currency, pricePerStay } = data.product.member.localPrice
      setNewPrice(formatPrice(intl, pricePerStay + extraPrice, currency))
    } else if ("public" in data.product && data.product.public) {
      const { currency, pricePerStay } = data.product.public.localPrice
      setNewPrice(formatPrice(intl, pricePerStay + extraPrice, currency))
    } else if (
      "corporateCheque" in data.product &&
      data.product.corporateCheque.localPrice.numberOfCheques
    ) {
      const { additionalPricePerStay, currency, numberOfCheques } =
        data.product.corporateCheque.localPrice
      setNewPrice(
        formatPrice(
          intl,
          numberOfCheques,
          CurrencyEnum.CC,
          additionalPricePerStay + extraPrice,
          currency?.toString() ?? pkgsSum.currency ?? currencyCode
        )
      )
    } else if (
      "voucher" in data.product &&
      data.product.voucher.numberOfVouchers
    ) {
      const { numberOfVouchers } = data.product.voucher
      setNewPrice(formatPrice(intl, numberOfVouchers, CurrencyEnum.Voucher))
    } else if (
      "redemption" in data.product &&
      data.product.redemption.localPrice.additionalPricePerStay
    ) {
      const { additionalPricePerStay, currency, pointsPerStay } =
        data.product.redemption.localPrice
      setNewPrice(
        formatPrice(
          intl,
          pointsPerStay,
          CurrencyEnum.POINTS,
          additionalPricePerStay + extraPrice,
          currency?.toString() ?? pkgsSum.currency ?? currencyCode
        )
      )
    }
  }

  function goBackToSelectDates() {
    setNewPrice(null)
    setDates(null)
    setNoAvailability(false)
  }

  const hasNewDate = newPrice && dates

  const stepOne = !hasNewDate
  const stepTwo = hasNewDate
  return (
    <>
      {stepOne ? (
        <Form
          checkAvailability={checkAvailability}
          closeModal={closeModal}
          noAvailability={noAvailability}
        />
      ) : null}
      {stepTwo ? (
        <Confirmation
          checkInDate={dates.fromDate}
          checkOutDate={dates.toDate}
          closeModal={goBackToSelectDates}
          newPrice={newPrice}
        />
      ) : null}
    </>
  )
}
