"use client"

import { useState } from "react"
import {
  Dialog,
  DialogTrigger,
  Modal,
  ModalOverlay,
  Popover,
  Radio,
  RadioGroup,
} from "react-aria-components"
import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"

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

import { trpc } from "@/lib/trpc/client"
import { useRatesStore } from "@/stores/select-rate"

import { useRoomContext } from "@/contexts/SelectRate/Room"
import useLang from "@/hooks/useLang"

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

import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
import { RateTypeEnum } from "@/types/enums/rateType"

export default function BookingCodeFilter() {
  const intl = useIntl()
  const lang = useLang()
  const [isOpen, setIsOpen] = useState(false)
  const displayAsPopover = useMediaQuery("(min-width: 768px)")
  const utils = trpc.useUtils()
  const {
    actions: { appendRegularRates, selectFilter },
    bookingRoom,
    rooms,
    selectedFilter,
    selectedPackages,
  } = useRoomContext()
  const booking = useRatesStore((state) => state.booking)

  const bookingCodeFilterItems = [
    {
      label: intl.formatMessage({
        defaultMessage: "Booking code rates",
      }),
      value: BookingCodeFilterEnum.Discounted,
    },
    {
      label: intl.formatMessage({
        defaultMessage: "All rates",
      }),
      value: BookingCodeFilterEnum.All,
    },
  ]

  async function updateFilterValue(selectedFilter: string) {
    selectFilter(selectedFilter as BookingCodeFilterEnum)
    if (selectedFilter === BookingCodeFilterEnum.All) {
      const room = await utils.hotel.availability.selectRate.room.fetch({
        booking: {
          ...booking,
          room: {
            ...bookingRoom,
            bookingCode: undefined,
            packages: selectedPackages.map((pkg) => pkg.code),
          },
        },
        lang,
      })
      appendRegularRates(room?.roomConfigurations)
    }
  }

  const hideFilter = rooms.some((room) =>
    room.products.some((product) => {
      const isRedemption = Array.isArray(product)
      if (isRedemption) {
        return true
      }

      switch (product.rateDefinition.rateType) {
        case RateTypeEnum.Arb:
        case RateTypeEnum.CorporateCheque:
        case RateTypeEnum.Voucher:
          return true
        default:
          return false
      }
    })
  )

  if (hideFilter || !booking.bookingCode) {
    return null
  }

  return (
    <>
      <div className={styles.bookingCodeFilter}>
        <DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
          <ChipButton variant="Outlined">
            {
              bookingCodeFilterItems.find(
                (item) => item.value === selectedFilter
              )?.label
            }
            <MaterialIcon
              icon="keyboard_arrow_down"
              size={20}
              color="CurrentColor"
            />
          </ChipButton>
          {displayAsPopover ? (
            <Popover placement="bottom end">
              <Dialog className={styles.dialog}>
                {({ close }) => {
                  function handleChangeFilterValue(value: string) {
                    updateFilterValue(value)
                    close()
                  }
                  return (
                    <Typography variant="Body/Paragraph/mdRegular">
                      <RadioGroup
                        aria-label={intl.formatMessage({
                          defaultMessage: "Booking Code Filter",
                        })}
                        onChange={handleChangeFilterValue}
                        name="bookingCodeFilter"
                        value={selectedFilter}
                        className={styles.radioGroup}
                      >
                        {bookingCodeFilterItems.map((item) => (
                          <Radio
                            aria-label={item.label}
                            key={item.value}
                            value={item.value}
                            className={styles.radio}
                            autoFocus={selectedFilter === item.value}
                          >
                            {item.label}
                          </Radio>
                        ))}
                      </RadioGroup>
                    </Typography>
                  )
                }}
              </Dialog>
            </Popover>
          ) : (
            <ModalOverlay className={styles.modalOverlay} isDismissable>
              <Modal className={styles.modal}>
                <Dialog className={styles.modalDialog}>
                  {({ close }) => {
                    function handleChangeFilterValue(value: string) {
                      updateFilterValue(value)
                      close()
                    }
                    return (
                      <>
                        <div className={styles.header}>
                          <Typography variant="Title/Subtitle/md">
                            <h3>
                              {intl.formatMessage({
                                defaultMessage: "Room rates",
                              })}
                            </h3>
                          </Typography>
                          <IconButton
                            theme="Black"
                            style="Muted"
                            onPress={() => {
                              close()
                            }}
                          >
                            <MaterialIcon
                              icon="close"
                              size={24}
                              color="CurrentColor"
                            />
                          </IconButton>
                        </div>
                        <Typography variant="Body/Paragraph/mdRegular">
                          <RadioGroup
                            aria-label={intl.formatMessage({
                              defaultMessage: "Booking Code Filter",
                            })}
                            onChange={handleChangeFilterValue}
                            name="bookingCodeFilter"
                            value={selectedFilter}
                            className={styles.radioGroup}
                          >
                            {bookingCodeFilterItems.map((item) => (
                              <Radio
                                aria-label={item.label}
                                key={item.value}
                                value={item.value}
                                className={styles.radio}
                              >
                                {item.label}
                              </Radio>
                            ))}
                          </RadioGroup>
                        </Typography>
                      </>
                    )
                  }}
                </Dialog>
              </Modal>
            </ModalOverlay>
          )}
        </DialogTrigger>
      </div>
    </>
  )
}
