"use client"

import { useRatesStore } from "@/stores/select-rate"

import { RoomContext } from "@/contexts/SelectRate/Room"
import { sortRoomConfigs } from "@/utils/sort"

import { AvailabilityEnum } from "@/types/components/hotelReservation/selectHotel/selectHotel"
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import type { RoomProviderProps } from "@/types/providers/select-rate/room"

export default function RoomProvider({
  children,
  idx,
  room,
}: RoomProviderProps) {
  const { activeRoom, rateSummary, roomAvailability, roomPackages } =
    useRatesStore((state) => ({
      activeRoom: state.activeRoom,
      rateSummary: state.rateSummary,
      roomPackages: state.roomsPackages[idx],
      roomAvailability: state.roomsAvailability?.[idx],
    }))
  const roomNr = idx + 1

  const petRoomPackage = roomPackages.find(
    (pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
  )

  const selectedRoomsCount = rateSummary.reduce<Record<string, number>>(
    (roomsCount, selectedRoom) => {
      if (selectedRoom) {
        if (!roomsCount[selectedRoom.roomTypeCode]) {
          roomsCount[selectedRoom.roomTypeCode] = 0
        }
        roomsCount[selectedRoom.roomTypeCode] =
          roomsCount[selectedRoom.roomTypeCode] + 1
      }
      return roomsCount
    },
    {}
  )

  const rooms = room.rooms
    .map((r) => {
      // Need to copy (shallow) since using immer with
      // Zustand uses Proxy objects which results in
      // properties being read-only thus causing errors
      // when trying to modify roomsLeft etc.
      const rCopy = { ...r }
      if (selectedRoomsCount[r.roomTypeCode]) {
        rCopy.roomsLeft =
          rCopy.roomsLeft - selectedRoomsCount[rCopy.roomTypeCode]

        const selectedRoom = rateSummary[idx]
        const isCurrentlySelectedRoom =
          selectedRoom && selectedRoom.roomTypeCode === rCopy.roomTypeCode
        if (isCurrentlySelectedRoom) {
          // Need to add 1 roomsLeft back to tally since
          // our selectedRoom was included in selectedRoomsCount
          rCopy.roomsLeft = rCopy.roomsLeft + 1
        }

        if (rCopy.roomsLeft <= 0) {
          rCopy.status = AvailabilityEnum.NotAvailable
          rCopy.roomsLeft = 0
        }
      }

      return rCopy
    })
    .sort(sortRoomConfigs)

  return (
    <RoomContext.Provider
      value={{
        ...room,
        isActiveRoom: activeRoom === idx,
        isMainRoom: roomNr === 1,
        petRoomPackage,
        roomAvailability,
        roomPackages,
        roomNr,
        rooms,
        totalRooms: room.rooms.length,
      }}
    >
      {children}
    </RoomContext.Provider>
  )
}
