"use client"

import {
  Button,
  Dialog,
  DialogTrigger,
  Modal,
  Popover,
} from "react-aria-components"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"

import Body from "@/components/TempDesignSystem/Text/Body"

import PickerForm from "./Form"

import styles from "./guests-rooms-picker.module.css"

import { GuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"

export default function GuestsRoomsPickerForm() {
  const { watch } = useFormContext()
  const rooms = watch("rooms") as GuestsRoom[]

  const isDesktop = useMediaQuery("(min-width: 1367px)")

  const htmlElement =
    typeof window !== "undefined" ? document.querySelector("body") : null
  //isOpen is the 'old state', so isOpen === true means "The modal is open and WILL be closed".
  function setOverflowClip(isOpen: boolean) {
    if (htmlElement) {
      if (isOpen) {
        htmlElement.style.overflow = "visible"
      } else {
        // !important needed to override 'overflow: hidden' set by react-aria.
        // 'overflow: hidden' does not work in combination with other sticky positioned elements, which clip does.
        htmlElement.style.overflow = "clip !important"
      }
    }
  }

  return isDesktop ? (
    <DialogTrigger onOpenChange={setOverflowClip}>
      <Trigger rooms={rooms} className={styles.triggerDesktop} />
      <Popover placement="bottom start" offset={36}>
        <Dialog className={styles.pickerContainerDesktop}>
          {({ close }) => <PickerForm rooms={rooms} onClose={close} />}
        </Dialog>
      </Popover>
    </DialogTrigger>
  ) : (
    <DialogTrigger>
      <Trigger rooms={rooms} className={styles.triggerMobile} />
      <Modal>
        <Dialog className={styles.pickerContainerMobile}>
          {({ close }) => <PickerForm rooms={rooms} onClose={close} />}
        </Dialog>
      </Modal>
    </DialogTrigger>
  )
}

function Trigger({
  rooms,
  className,
}: {
  rooms: GuestsRoom[]
  className: string
}) {
  const intl = useIntl()

  return (
    <Button className={`${className} ${styles.btn}`} type="button">
      <Body>
        {rooms.map((room, i) => (
          <span key={i}>
            {intl.formatMessage(
              { id: "booking.rooms" },
              { totalRooms: rooms.length }
            )}
            {", "}
            {intl.formatMessage(
              { id: "booking.adults" },
              { totalAdults: room.adults }
            )}
            {room.child.length > 0
              ? ", " +
                intl.formatMessage(
                  { id: "booking.children" },
                  { totalChildren: room.child.length }
                )
              : null}
          </span>
        ))}
      </Body>
    </Button>
  )
}
