import { ChevronDown } from "lucide-react";
import type { FocusEvent } from "react";
import { useMemo, useState } from "react";

export type SelectOption = {
  value: string;
  label: string;
};

type SelectFieldProps = {
  label?: string;
  value: string;
  options: SelectOption[];
  placeholder?: string;
  onChange: (value: string) => void;
};

export function SelectField({ label, value, options, placeholder = "Select", onChange }: SelectFieldProps) {
  const [open, setOpen] = useState(false);
  const selectedOption = useMemo(() => options.find((option) => option.value === value), [options, value]);
  const closeOnOutsideBlur = (event: FocusEvent<HTMLDivElement>) => {
    const nextTarget = event.relatedTarget;
    if (!(nextTarget instanceof Node) || !event.currentTarget.contains(nextTarget)) {
      setOpen(false);
    }
  };
  const control = (
    <div className="select-field" onBlur={closeOnOutsideBlur}>
      <button className={`select-trigger ${open ? "open" : ""}`} type="button" aria-haspopup="listbox" aria-expanded={open} onClick={() => setOpen(!open)}>
        <span>{selectedOption?.label ?? placeholder}</span>
        <ChevronDown size={16} />
      </button>
      {open && (
        <div className="select-menu" role="listbox">
          {options.map((option) => (
            <button
              className={option.value === value ? "select-option active" : "select-option"}
              key={option.value}
              role="option"
              type="button"
              aria-selected={option.value === value}
              onClick={() => {
                onChange(option.value);
                setOpen(false);
              }}
            >
              {option.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );

  if (!label) return control;
  return (
    <label>
      {label}
      {control}
    </label>
  );
}
