import { RoomConfiguration } from "@/server/routers/hotels/output"

/**
 * Get the lowest priced room for each room type that appears more than once.
 */

export function filterDuplicateRoomTypesByLowestPrice(
  roomConfigurations: RoomConfiguration[]
) {
  const roomTypeCount = roomConfigurations.reduce(
    (acc, room) => {
      acc[room.roomType] = (acc[room.roomType] || 0) + 1
      return acc
    },
    {} as Record<string, number>
  )

  const duplicateRoomTypes = new Set(
    Object.keys(roomTypeCount).filter((roomType) => roomTypeCount[roomType] > 1)
  )

  const roomMap = new Map()

  roomConfigurations.forEach((room) => {
    const { roomType, products } = room

    if (!duplicateRoomTypes.has(roomType)) {
      roomMap.set(roomType, room)
      return
    }

    products.forEach((product) => {
      const { productType } = product
      const publicProduct = productType.public
      const memberProduct = productType.member || {
        requestedPrice: null,
        localPrice: null,
      }

      const {
        requestedPrice: publicRequestedPrice,
        localPrice: publicLocalPrice,
      } = publicProduct
      const {
        requestedPrice: memberRequestedPrice,
        localPrice: memberLocalPrice,
      } = memberProduct

      const previousLowest = roomMap.get(roomType)

      const currentRequestedPrice = Math.min(
        Number(publicRequestedPrice.pricePerNight) ?? Infinity,
        Number(memberRequestedPrice?.pricePerNight) ?? Infinity
      )
      const currentLocalPrice = Math.min(
        Number(publicLocalPrice.pricePerNight) ?? Infinity,
        Number(memberLocalPrice?.pricePerNight) ?? Infinity
      )

      if (
        !previousLowest ||
        currentRequestedPrice <
          Math.min(
            Number(
              previousLowest.products[0].productType.public.requestedPrice
                .pricePerNight
            ) ?? Infinity,
            Number(
              previousLowest.products[0].productType.member?.requestedPrice
                ?.pricePerNight
            ) ?? Infinity
          ) ||
        (currentRequestedPrice ===
          Math.min(
            Number(
              previousLowest.products[0].productType.public.requestedPrice
                .pricePerNight
            ) ?? Infinity,
            Number(
              previousLowest.products[0].productType.member?.requestedPrice
                ?.pricePerNight
            ) ?? Infinity
          ) &&
          currentLocalPrice <
            Math.min(
              Number(
                previousLowest.products[0].productType.public.localPrice
                  .pricePerNight
              ) ?? Infinity,
              Number(
                previousLowest.products[0].productType.member?.localPrice
                  ?.pricePerNight
              ) ?? Infinity
            ))
      ) {
        roomMap.set(roomType, room)
      }
    })
  })

  return Array.from(roomMap.values())
}
