"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 { _ } from "@/lib/translation"

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",
  placeholder = "Select a country",
  registerOptions,
}: CountryProps) {
  const divRef = useRef<HTMLDivElement>(null)
  const { control, setValue } = useFormContext()
  const { field } = useController({
    control,
    name,
    rules: registerOptions,
  })

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

  return (
    <div className={styles.container} ref={divRef}>
      <ComboBox
        aria-label={_("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}>
          <Input
            aria-label="Selected country"
            className={styles.input}
            placeholder={_(placeholder)}
          />
          <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) => (
              <ListBoxItem
                aria-label={country.name}
                className={styles.listBoxItem}
                id={country.code}
                key={`${country.code}-${idx}`}
              >
                {country.name}
              </ListBoxItem>
            ))}
          </ListBox>
        </Popover>
      </ComboBox>
    </div>
  )
}
