"use client"
import { useController, useFormContext } from "react-hook-form"
import { useEffect, useRef, useState } from "react"

import { _ } from "@/lib/translation"
import { countries } from "./countries"

import {
  Button,
  ComboBox,
  FieldError,
  Input,
  ListBox,
  ListBoxItem,
  Popover,
  type Key,
} from "react-aria-components"
import { ErrorMessage } from "@hookform/error-message"
import SelectChevron from "../SelectChevron"

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 [divElement, setDivElement] = useState(divRef.current)
  const { control, setValue } = useFormContext()
  const { field } = useController({
    control,
    name,
    rules: registerOptions,
  })
  const [selectedKey, setSelectedKey] = useState(() => {
    if (field.value) {
      const selected = countries.find(
        (country) =>
          country.name === field.value || country.code === field.value
      )
      if (selected) {
        return selected.name
      }
    }
    return ""
  })

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

  useEffect(() => {
    if (divRef.current) {
      setDivElement(divRef.current)
    }
  }, [divRef.current])

  return (
    <div className={styles.container} ref={divRef}>
      <ComboBox
        className={styles.select}
        isRequired={!!registerOptions?.required}
        name={field.name}
        onBlur={field.onBlur}
        onSelectionChange={handleChange}
        ref={field.ref}
        selectedKey={selectedKey}
      >
        <div className={styles.comboBoxContainer}>
          <Input 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={divElement ?? undefined}
        >
          <ListBox>
            {countries.map((country, idx) => (
              <ListBoxItem
                className={styles.listBoxItem}
                id={country.name}
                key={`${country.code}-${idx}`}
              >
                {country.name}
              </ListBoxItem>
            ))}
          </ListBox>
        </Popover>
      </ComboBox>
    </div>
  )
}
