"use client"
import { useState } from "react"
import {
  Button,
  ComboBox,
  Input,
  type Key,
  ListBox,
  ListBoxItem,
  Popover,
} from "react-aria-components"
import { useController, useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"

import Label from "@/components/TempDesignSystem/Form/Label"
import SelectChevron from "@/components/TempDesignSystem/Form/SelectChevron"
import Body from "@/components/TempDesignSystem/Text/Body"

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

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

import type {
  CountryPortalContainer,
  CountryPortalContainerArgs,
  CountryProps,
} from "./country"

export default function CountrySelect({
  className = "",
  label,
  name = "country",
  readOnly = false,
  registerOptions = {},
}: CountryProps) {
  const { formatMessage } = useIntl()
  const [rootDiv, setRootDiv] = useState<CountryPortalContainer>(undefined)

  function setRef(node: CountryPortalContainerArgs) {
    if (node) {
      setRootDiv(node)
    }
  }
  const { control, setValue } = useFormContext()
  const { field, fieldState, formState } = useController({
    control,
    name,
    rules: registerOptions,
  })

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

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

  return (
    <div className={`${styles.container} ${className}`} ref={setRef}>
      <ComboBox
        aria-label={formatMessage({ id: "Select country of residence" })}
        className={styles.select}
        isInvalid={fieldState.invalid}
        isReadOnly={readOnly}
        isRequired={!!registerOptions?.required}
        name={field.name}
        onBlur={field.onBlur}
        onSelectionChange={handleChange}
        ref={field.ref}
        selectedKey={field.value}
        data-testid={name}
      >
        <div className={styles.comboBoxContainer}>
          <Label
            className={styles.label}
            size="small"
            required={!!registerOptions.required}
          >
            {label}
          </Label>
          <Body asChild fontOnly>
            <Input
              aria-label={selectCountryLabel}
              className={styles.input}
              placeholder={selectCountryLabel}
            />
          </Body>
          <Button className={styles.button}>
            <SelectChevron />
          </Button>
        </div>
        <ErrorMessage errors={formState.errors} name={name} />
        <Popover
          className={styles.popover}
          placement="bottom"
          shouldFlip={false}
          shouldUpdatePosition={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={rootDiv}
        >
          <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>
  )
}
