"use client"
import { produce } from "immer"
import { useContext } from "react"
import { create, useStore } from "zustand"

import { mapRoomDetails } from "@/components/HotelReservation/MyStay/utils/mapRoomDetails"
import { MyStayContext } from "@/contexts/MyStay"
import { getBookedHotelRoom } from "@/utils/booking"

import {
  calculateTotalPoints,
  calculateTotalPrice,
  isAllRoomsCancelled,
} from "./helpers"

import type { InitialState, MyStayState } from "@/types/stores/my-stay"

export function createMyStayStore({
  breakfastPackages,
  hotel,
  intl,
  refId,
  roomCategories,
  rooms,
  savedCreditCards,
}: InitialState) {
  const rates = {
    change: intl.formatMessage({
      defaultMessage: "Free rebooking",
    }),
    flex: intl.formatMessage({
      defaultMessage: "Free cancellation",
    }),
    save: intl.formatMessage({
      defaultMessage: "Non-refundable",
    }),
  }

  const mappedRooms = rooms.map((booking, idx) => {
    const room = getBookedHotelRoom(roomCategories, booking.roomTypeCode)
    return mapRoomDetails({
      booking,
      rates,
      room,
      roomNumber: idx + 1,
    })
  })
  const bookedRoom = mappedRooms[0]

  const allRoomsAreCancelled = isAllRoomsCancelled(mappedRooms)

  const totalPoints = calculateTotalPoints(mappedRooms, allRoomsAreCancelled)

  const totalPrice = calculateTotalPrice(
    mappedRooms,
    bookedRoom.currencyCode,
    intl,
    allRoomsAreCancelled
  )

  const mainRoom = mappedRooms.find((r) => r.mainRoom) ?? bookedRoom

  return create<MyStayState>()((set) => {
    return {
      allRoomsAreCancelled,
      bookedRoom,
      breakfastPackages,
      hotel,
      mainRoom,
      manageStay: false,
      refId,
      rooms: mappedRooms,
      savedCreditCards,
      totalPoints,
      totalPrice,

      actions: {
        closeManageStay() {
          return set(
            produce((state: MyStayState) => {
              state.manageStay = false
            })
          )
        },
        openManageStay() {
          return set(
            produce((state: MyStayState) => {
              state.manageStay = true
            })
          )
        },
      },
    }
  })
}

export function useMyStayStore<T>(selector: (store: MyStayState) => T) {
  const store = useContext(MyStayContext)

  if (!store) {
    throw new Error("useMyStayStore must be used within MyStayProvider")
  }

  return useStore(store, selector)
}
