"use client"
import { useState } from "react"
import {
  Button,
  type Key,
  Label,
  ListBox,
  ListBoxItem,
  Popover,
  Select as ReactAriaSelect,
  SelectValue,
} from "react-aria-components"

import Body from "../../Text/Body"
import Footnote from "../../Text/Footnote"
import SelectChevron from "../SelectChevron"

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

import type { SelectPortalContainer, SelectProps } from "./select"

export default function Select({
  "aria-label": ariaLabel,
  items,
  label,
  onSelect,
  placeholder,
  value,
  defaultSelectedKey,
}: SelectProps) {
  const [rootDiv, setRootDiv] = useState<SelectPortalContainer>(null)

  function setRef(node: SelectPortalContainer) {
    if (node) {
      setRootDiv(node)
    }
  }

  function handleOnSelect(key: Key) {
    onSelect(key)
  }

  return (
    <div className={styles.container} ref={setRef}>
      <ReactAriaSelect
        defaultSelectedKey={defaultSelectedKey}
        aria-label={ariaLabel}
        className={styles.select}
        onSelectionChange={handleOnSelect}
        placeholder={placeholder}
        selectedKey={value as Key}
      >
        <Body asChild fontOnly>
          <Button className={styles.input}>
            <div className={styles.inputContentWrapper}>
              <Footnote asChild fontOnly>
                <Label className={styles.label}>{label}</Label>
              </Footnote>
              <SelectValue />
            </div>
            <SelectChevron />
          </Button>
        </Body>
        <Body asChild fontOnly>
          <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={rootDiv ?? undefined}
          >
            <ListBox className={styles.listBox}>
              {items.map((item) => (
                <ListBoxItem
                  aria-label={String(item)}
                  className={styles.listBoxItem}
                  id={item.value}
                  key={item.label}
                >
                  {item.label}
                </ListBoxItem>
              ))}
            </ListBox>
          </Popover>
        </Body>
      </ReactAriaSelect>
    </div>
  )
}
