"use client"

import { useCallback, useState } from "react"

import useRoomAvailableStore from "@/stores/roomAvailability"

import RoomFilter from "../RoomFilter"
import RoomSelection from "../RoomSelection"
import { filterDuplicateRoomTypesByLowestPrice } from "./utils"

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

import {
  DefaultFilterOptions,
  RoomPackageCodeEnum,
  type RoomPackageCodes,
} from "@/types/components/hotelReservation/selectRate/roomFilter"
import type { SelectRateProps } from "@/types/components/hotelReservation/selectRate/roomSelection"
import type { Rate } from "@/types/components/hotelReservation/selectRate/selectRate"
import type {
  RoomConfiguration,
  RoomsAvailability,
} from "@/server/routers/hotels/output"

export default function Rooms({
  roomsAvailability,
  roomCategories = [],
  user,
  availablePackages,
}: SelectRateProps) {
  const visibleRooms: RoomConfiguration[] =
    filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
  const [rateSummary, setRateSummary] = useState<Rate | null>(null)
  const [rooms, setRooms] = useState<RoomsAvailability>({
    ...roomsAvailability,
    roomConfigurations: visibleRooms,
  })
  const [selectedPackages, setSelectedPackages] = useState<RoomPackageCodes[]>(
    []
  )
  const noRoomsAvailable = useRoomAvailableStore(
    (state) => state.noRoomsAvailable
  )
  const setNoRoomsAvailable = useRoomAvailableStore(
    (state) => state.setNoRoomsAvailable
  )
  const setRoomsAvailable = useRoomAvailableStore(
    (state) => state.setRoomsAvailable
  )

  const defaultPackages: DefaultFilterOptions[] = [
    {
      code: RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
      description: "Accessible Room",
      itemCode: availablePackages.find(
        (pkg) => pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM
      )?.itemCode,
    },
    {
      code: RoomPackageCodeEnum.ALLERGY_ROOM,
      description: "Allergy Room",
      itemCode: availablePackages.find(
        (pkg) => pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM
      )?.itemCode,
    },
    {
      code: RoomPackageCodeEnum.PET_ROOM,
      description: "Pet Room",
      itemCode: availablePackages.find(
        (pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
      )?.itemCode,
    },
  ]

  const handleFilter = useCallback(
    (filter: Record<RoomPackageCodeEnum, boolean | undefined>) => {
      const filteredPackages = Object.keys(filter).filter(
        (key) => filter[key as RoomPackageCodeEnum]
      ) as RoomPackageCodeEnum[]

      setSelectedPackages(filteredPackages)

      if (filteredPackages.length === 0) {
        setRooms({
          ...roomsAvailability,
          roomConfigurations: visibleRooms,
        })

        if (!!rateSummary) {
          setRateSummary({
            ...rateSummary,
            features: [],
          })
        }

        if (noRoomsAvailable) {
          setRoomsAvailable()
        }

        return
      }

      const filteredRooms = visibleRooms.filter((room) =>
        filteredPackages.every((filteredPackage) =>
          room.features.some((feature) => feature.code === filteredPackage)
        )
      )

      setRooms({
        ...roomsAvailability,
        roomConfigurations: [...filteredRooms],
      })

      if (filteredRooms.length == 0) {
        setNoRoomsAvailable()
      } else if (noRoomsAvailable) {
        setRoomsAvailable()
      }

      const petRoomPackage =
        (filteredPackages.includes(RoomPackageCodeEnum.PET_ROOM) &&
          availablePackages.find(
            (pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
          )) ||
        undefined

      const features = filteredRooms.find((room) =>
        room.features.some(
          (feature) => feature.code === RoomPackageCodeEnum.PET_ROOM
        )
      )?.features

      if (!!rateSummary) {
        setRateSummary({
          ...rateSummary,
          features: petRoomPackage && features ? features : [],
        })
      }
    },
    [
      roomsAvailability,
      visibleRooms,
      rateSummary,
      availablePackages,
      noRoomsAvailable,
      setNoRoomsAvailable,
      setRoomsAvailable,
    ]
  )

  return (
    <div className={styles.content}>
      <RoomFilter
        numberOfRooms={rooms.roomConfigurations.length}
        onFilter={handleFilter}
        filterOptions={defaultPackages}
      />
      <RoomSelection
        roomsAvailability={rooms}
        roomCategories={roomCategories}
        user={user}
        availablePackages={availablePackages}
        selectedPackages={selectedPackages}
        setRateSummary={setRateSummary}
        rateSummary={rateSummary}
      />
    </div>
  )
}
