"use client"
import { ErrorMessage } from "@hookform/error-message"
import { useRef } from "react"
import {
  Button,
  ComboBox,
  FieldError,
  Input,
  type Key,
  ListBox,
  ListBoxItem,
  Popover,
} from "react-aria-components"
import { useController, useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"

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

import SelectChevron from "../SelectChevron"
import { countries } from "./countries"

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

import type { CountryProps } from "./country"

export default function CountrySelect({
  name = "country",
  registerOptions,
}: CountryProps) {
  const { formatMessage } = useIntl()
  const divRef = useRef<HTMLDivElement>(null)
  const { control, setValue } = useFormContext()
  const { field } = useController({
    control,
    name,
    rules: registerOptions,
  })

  function handleChange(country: Key) {
    setValue(name, country)
  }

  const selectCountryLabel = formatMessage({ id: "Select a country" })

  return (
    <div className={styles.container} ref={divRef}>
      <ComboBox
        aria-label={formatMessage({ id: "Select country of residence" })}
        className={styles.select}
        isRequired={!!registerOptions?.required}
        name={field.name}
        onBlur={field.onBlur}
        onSelectionChange={handleChange}
        ref={field.ref}
        selectedKey={field.value}
      >
        <div className={styles.comboBoxContainer}>
          <Body asChild fontOnly>
            <Input
              aria-label={selectCountryLabel}
              className={styles.input}
              placeholder={selectCountryLabel}
            />
          </Body>
          <Button className={styles.button}>
            <SelectChevron />
          </Button>
        </div>
        <FieldError>
          <ErrorMessage name={name} />
        </FieldError>
        <Popover
          className={styles.popover}
          placement="bottom"
          shouldFlip={false}
          /**
           * react-aria uses portals to render Popover in body
           * unless otherwise specified. We need it to be contained
           * by this component to both access css variables assigned
           * on the container as well as to not overflow it at any time.
           */
          UNSTABLE_portalContainer={divRef.current ?? undefined}
        >
          <ListBox>
            {countries.map((country, idx) => (
              <Body asChild fontOnly key={`${country.code}-${idx}`}>
                <ListBoxItem
                  aria-label={country.name}
                  className={styles.listBoxItem}
                  id={country.code}
                >
                  {country.name}
                </ListBoxItem>
              </Body>
            ))}
          </ListBox>
        </Popover>
      </ComboBox>
    </div>
  )
}
