"use client"

import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"

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

import Select from "@/components/TempDesignSystem/Select"
import Caption from "@/components/TempDesignSystem/Text/Caption"

import styles from "./child-selector.module.css"

import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type {
  ChildBed,
  ChildInfoSelectorProps,
} from "@/types/components/bookingWidget/guestsRoomsPicker"

const ageList = [...Array(13)].map((_, i) => ({
  label: i.toString(),
  value: i,
}))

const childDefaultValues = { age: -1, bed: -1 }

export default function ChildInfoSelector({
  child,
  childrenInAdultsBed,
  adults,
  index = 0,
  roomIndex = 0,
}: ChildInfoSelectorProps) {
  const ageFieldName = `rooms.${roomIndex}.childrenInRoom.${index}.age`
  const bedFieldName = `rooms.${roomIndex}.childrenInRoom.${index}.bed`
  const intl = useIntl()
  const ageLabel = intl.formatMessage({
    defaultMessage: "Age",
  })
  const bedLabel = intl.formatMessage({
    defaultMessage: "Bed preference",
  })
  const errorMessage = intl.formatMessage({
    defaultMessage: "Child age is required",
  })
  const { setValue, formState } = useFormContext()

  function updateSelectedBed(bed: number) {
    setValue(`rooms.${roomIndex}.childrenInRoom.${index}.bed`, bed)
  }

  function updateSelectedAge(age: number) {
    setValue(`rooms.${roomIndex}.childrenInRoom.${index}.age`, age)
    const availableBedTypes = getAvailableBeds(age)
    updateSelectedBed(availableBedTypes[0].value)
  }

  const allBedTypes: ChildBed[] = [
    {
      label: intl.formatMessage({
        defaultMessage: "In adult's bed",
      }),
      value: ChildBedMapEnum.IN_ADULTS_BED,
    },
    {
      label: intl.formatMessage({
        defaultMessage: "In crib",
      }),
      value: ChildBedMapEnum.IN_CRIB,
    },
    {
      label: intl.formatMessage({
        defaultMessage: "In extra bed",
      }),
      value: ChildBedMapEnum.IN_EXTRA_BED,
    },
  ]

  function getAvailableBeds(age: number) {
    let availableBedTypes: ChildBed[] = []
    if (age <= 5 && (adults > childrenInAdultsBed || child.bed === 0)) {
      availableBedTypes.push(allBedTypes[0])
    }
    if (age < 3) {
      availableBedTypes.push(allBedTypes[1])
    }
    if (age > 2) {
      availableBedTypes.push(allBedTypes[2])
    }
    return availableBedTypes
  }

  const roomErrors =
    //@ts-expect-error: formState is typed with FormValues
    formState.errors.rooms?.[roomIndex]?.childrenInRoom?.[index]

  const ageError = roomErrors?.age
  const bedError = roomErrors?.bed

  return (
    <>
      <div key={index} className={styles.childInfoContainer}>
        <div>
          <Select
            required={true}
            items={ageList}
            label={ageLabel}
            aria-label={ageLabel}
            value={child.age ?? childDefaultValues.age}
            onSelect={(key) => {
              updateSelectedAge(key as number)
            }}
            maxHeight={180}
            name={ageFieldName}
            isNestedInModal={true}
          />
        </div>
        <div>
          {child.age >= 0 ? (
            <Select
              items={getAvailableBeds(child.age)}
              label={bedLabel}
              aria-label={bedLabel}
              value={child.bed ?? childDefaultValues.bed}
              onSelect={(key) => {
                updateSelectedBed(key as number)
              }}
              name={bedFieldName}
              isNestedInModal={true}
            />
          ) : null}
        </div>
      </div>

      {roomErrors && roomErrors.message ? (
        <Caption color="red" className={styles.error}>
          <MaterialIcon icon="error" color="Icon/Interactive/Accent" />
          {roomErrors.message}
        </Caption>
      ) : null}

      {ageError || bedError ? (
        <Caption color="red" className={styles.error}>
          <MaterialIcon icon="error" color="Icon/Interactive/Accent" />
          {errorMessage}
        </Caption>
      ) : null}
    </>
  )
}
