"use client"

import { useCallback, useEffect, useRef } from "react"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"

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

import { REDEMPTION } from "@/constants/booking"

import Modal from "@/components/Modal"
import Button from "@/components/TempDesignSystem/Button"
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
import { getErrorMessage } from "@/components/TempDesignSystem/Form/Input/errors"
import Caption from "@/components/TempDesignSystem/Text/Caption"

import { RemoveExtraRooms } from "../BookingCode"

import styles from "./reward-night.module.css"

import type { BookingWidgetSchema } from "@/types/components/bookingWidget"

export default function RewardNight() {
  const intl = useIntl()
  const {
    setValue,
    getValues,
    formState: { errors },
    trigger,
  } = useFormContext<BookingWidgetSchema>()
  const ref = useRef<HTMLDivElement | null>(null)
  const reward = intl.formatMessage({
    defaultMessage: "Reward Night",
  })
  const rewardNightTooltip = intl.formatMessage({
    defaultMessage:
      "To book a reward night, make sure you're logged in to your Scandic Friends account.",
  })
  const redemptionErr = errors[REDEMPTION]
  const isMultiRoomError = redemptionErr?.message?.indexOf("Multi-room") === 0

  function validateRedemption(value: boolean) {
    // Validate redemption as per the rules defined in the schema
    trigger(REDEMPTION)
    if (value && getValues("bookingCode.value")) {
      setValue("bookingCode.flag", false)
      setValue("bookingCode.value", "", { shouldValidate: true })
      // Hide the notification popup after 5 seconds by re-triggering validation
      // This is kept consistent with location search field error notification timeout
      setTimeout(() => {
        trigger(REDEMPTION)
      }, 5000)
    }
  }

  const resetOnMultiroomError = useCallback(() => {
    if (isMultiRoomError) {
      setValue(REDEMPTION, false, { shouldValidate: true })
    }
  }, [isMultiRoomError, setValue])

  function closeOnBlur(evt: FocusEvent) {
    const target = evt.relatedTarget as HTMLElement
    if (ref.current && target && !ref.current.contains(target)) {
      resetOnMultiroomError()
    }
  }

  useEffect(() => {
    const clearIfOutside = function (evt: Event) {
      const target = evt.target as HTMLElement
      if (ref.current && target && !ref.current.contains(target)) {
        resetOnMultiroomError()
      }
    }
    document.body.addEventListener("click", clearIfOutside)
    return () => {
      document.body.removeEventListener("click", clearIfOutside)
    }
  }, [resetOnMultiroomError, ref])

  return (
    <div ref={ref} onBlur={(e) => closeOnBlur(e.nativeEvent)}>
      <Checkbox
        hideError
        name={REDEMPTION}
        registerOptions={{
          onChange: (e) => {
            validateRedemption(e.target.value)
          },
        }}
      >
        <div className={styles.rewardNightLabel}>
          <Caption color="uiTextMediumContrast" asChild>
            <span>{reward}</span>
          </Caption>
          <Modal
            trigger={
              <Button intent="text">
                <MaterialIcon
                  icon="info"
                  size={20}
                  color="Icon/Interactive/Placeholder"
                  className={styles.errorIcon}
                />
              </Button>
            }
            title={reward}
          >
            <Typography
              variant="Body/Paragraph/mdRegular"
              className={styles.rewardNightTooltip}
            >
              <span>{rewardNightTooltip}</span>
            </Typography>
          </Modal>
        </div>
      </Checkbox>
      {redemptionErr && (
        <div className={styles.errorContainer}>
          <Caption className={styles.error} type="regular" color="blue">
            <MaterialIcon
              icon="error"
              size={24}
              color="Icon/Feedback/Information"
              className={styles.errorIcon}
            />
            {getErrorMessage(intl, redemptionErr.message)}
          </Caption>
          {isMultiRoomError ? <RemoveExtraRooms /> : null}
        </div>
      )}
    </div>
  )
}
