"use client"

import { zodResolver } from "@hookform/resolvers/zod"
import { useCallback, useEffect, useState } from "react"
import { FormProvider, useForm } from "react-hook-form"

import {
  BED_TYPE_ICONS,
  type BedTypeEnum,
  type ExtraBedTypeEnum,
} from "@/constants/booking"
import { useEnterDetailsStore } from "@/stores/enter-details"

import RadioCard from "@/components/TempDesignSystem/Form/RadioCard"
import { useRoomContext } from "@/contexts/Details/Room"
import { trackBedSelection } from "@/utils/tracking"

import { bedTypeFormSchema } from "./schema"

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

import type { IconProps } from "@scandic-hotels/design-system/Icons"

import type { BedTypeFormSchema } from "@/types/components/hotelReservation/enterDetails/bedType"

export default function BedType() {
  const availableBeds = useEnterDetailsStore((state) => state.availableBeds)
  const {
    actions: { updateBedType },
    room: { bedType, bedTypes },
  } = useRoomContext()
  const initialBedType = bedType?.roomTypeCode
  const [previousBedType, setPreviousBedType] = useState("")

  const methods = useForm<BedTypeFormSchema>({
    criteriaMode: "all",
    mode: "all",
    resolver: zodResolver(bedTypeFormSchema),
    reValidateMode: "onChange",
    values: initialBedType ? { bedType: initialBedType } : undefined,
  })

  const onSubmit = useCallback(
    (bedTypeRoomCode: BedTypeFormSchema) => {
      const matchingRoom = bedTypes?.find(
        (roomType) => roomType.value === bedTypeRoomCode.bedType
      )
      if (matchingRoom) {
        const bedType = {
          description: matchingRoom.description,
          roomTypeCode: matchingRoom.value,
        }
        updateBedType(bedType)
        trackBedSelection(bedType.description)
      }
    },
    [bedTypes, updateBedType]
  )

  const selectedBedType = methods.watch("bedType")
  const handleSubmit = methods.handleSubmit
  useEffect(() => {
    if (selectedBedType && selectedBedType !== previousBedType) {
      handleSubmit(onSubmit)()
      setPreviousBedType(selectedBedType)
    }
  }, [
    selectedBedType,
    previousBedType,
    handleSubmit,
    onSubmit,
    setPreviousBedType,
  ])

  return (
    <FormProvider {...methods}>
      <div className={styles.container}>
        <form className={styles.form} onSubmit={methods.handleSubmit(onSubmit)}>
          {bedTypes.map((roomType) => {
            const width =
              roomType.size.max === roomType.size.min
                ? `${roomType.size.min} cm`
                : `${roomType.size.min} cm - ${roomType.size.max} cm`

            const bedAvailable = availableBeds[roomType.value]
            // This is needed since otherwise, picking the last room would make
            // the card disabled
            const isSameBedAsSelected = bedType?.roomTypeCode === roomType.value
            return (
              <RadioCard
                key={roomType.value}
                Icon={(props) => (
                  <BedIconRenderer
                    mainBedType={roomType.type}
                    extraBedType={roomType.extraBed?.type}
                    props={props}
                  />
                )}
                disabled={!bedAvailable && !isSameBedAsSelected}
                id={roomType.value}
                name="bedType"
                subtitle={width}
                title={roomType.description}
                value={roomType.value}
              />
            )
          })}
        </form>
      </div>
    </FormProvider>
  )
}

function BedIconRenderer({
  mainBedType,
  extraBedType,
  props,
}: {
  mainBedType: BedTypeEnum
  extraBedType: ExtraBedTypeEnum | undefined
  props: IconProps
}) {
  const MainBedIcon = BED_TYPE_ICONS[mainBedType] ?? BED_TYPE_ICONS.Other
  const ExtraBedIcon = extraBedType ? BED_TYPE_ICONS[extraBedType] : null

  if (!MainBedIcon) {
    return null
  }

  return (
    <div className={`${props.className} ${styles.iconContainer}`}>
      <MainBedIcon height={32} />
      {ExtraBedIcon && <ExtraBedIcon height={32} />}
    </div>
  )
}
