"use client"

import { useCallback, useEffect, useMemo, useState } from "react"

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 } from "@/server/routers/hotels/output"

export default function Rooms({
  roomsAvailability,
  roomCategories = [],
  user,
  availablePackages,
}: SelectRateProps) {
  const visibleRooms: RoomConfiguration[] =
    filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
  const [selectedRate, setSelectedRate] = useState<
    { publicRateCode: string; roomTypeCode: string } | undefined
  >(undefined)
  const [selectedPackages, setSelectedPackages] = useState<RoomPackageCodes[]>(
    []
  )
  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)
    },
    []
  )

  const filteredRooms = useMemo(() => {
    return visibleRooms.filter((room) =>
      selectedPackages.every((filteredPackage) =>
        room.features.some((feature) => feature.code === filteredPackage)
      )
    )
  }, [visibleRooms, selectedPackages])

  const rooms = useMemo(() => {
    if (selectedPackages.length === 0) {
      return {
        ...roomsAvailability,
        roomConfigurations: visibleRooms,
      }
    }

    return {
      ...roomsAvailability,
      roomConfigurations: [...filteredRooms],
    }
  }, [roomsAvailability, visibleRooms, selectedPackages, filteredRooms])

  const rateSummary: Rate | null = useMemo(() => {
    const room = filteredRooms.find(
      (room) => room.roomTypeCode === selectedRate?.roomTypeCode
    )

    if (!room) return null

    const product = room.products.find(
      (product) =>
        product.productType.public.rateCode === selectedRate?.publicRateCode
    )

    if (!product) return null

    const petRoomPackage =
      (selectedPackages.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

    const rateSummary: Rate = {
      features: petRoomPackage && features ? features : [],
      priceName: room.roomType,
      public: product.productType.public,
      member: product.productType.member,
      roomType: room.roomType,
      roomTypeCode: room.roomTypeCode,
    }

    return rateSummary
  }, [filteredRooms, availablePackages, selectedPackages, selectedRate])

  useEffect(() => {
    if (rateSummary) return
    if (!selectedRate) return

    setSelectedRate(undefined)
  }, [rateSummary, selectedRate])

  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}
        setRateCode={setSelectedRate}
        rateSummary={rateSummary}
      />
    </div>
  )
}
