"use client"

import { useCallback, useEffect, useState } from "react"
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 checkIsDesktop = useMediaQuery("(min-width: 1367px)")
  const [isDesktop, setIsDesktop] = useState(true)
  const [containerHeight, setContainerHeight] = useState(0)
  const childCount = rooms[0] ? rooms[0].child.length : 0 // ToDo Update for multiroom later

  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"
      }
    }
  }

  useEffect(() => {
    setIsDesktop(checkIsDesktop)
  }, [checkIsDesktop])

  const updateHeight = useCallback(() => {
    if (typeof window !== undefined) {
      // Get available space for picker to show without going beyond screen
      let maxHeight =
        window.innerHeight -
        (document.querySelector("#booking-widget")?.getBoundingClientRect()
          .bottom ?? 0) -
        50
      const innerContainerHt = document
        .querySelector(".react-aria-Popover")
        ?.getBoundingClientRect().height
      if (
        maxHeight != containerHeight &&
        innerContainerHt &&
        maxHeight <= innerContainerHt
      ) {
        setContainerHeight(maxHeight)
      } else if (
        containerHeight &&
        innerContainerHt &&
        maxHeight > innerContainerHt
      ) {
        setContainerHeight(0)
      }
    }
  }, [containerHeight])

  useEffect(() => {
    if (typeof window !== undefined && isDesktop) {
      updateHeight()
    }
  }, [childCount, isDesktop, updateHeight])

  return isDesktop ? (
    <DialogTrigger onOpenChange={setOverflowClip}>
      <Trigger rooms={rooms} className={styles.triggerDesktop} />
      <Popover
        placement="bottom start"
        offset={36}
        style={containerHeight ? { overflow: "auto" } : {}}
      >
        <Dialog className={styles.pickerContainerDesktop}>
          {({ close }) => (
            <PickerForm
              rooms={rooms}
              onClose={close}
              isOverflowed={!!containerHeight}
            />
          )}
        </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>
  )
}
