import { useEffect, useMemo, useRef, useState } from "react";
import styles from "./SimpleSelect.module.css";

type Option = { value: string | number; label: string };

type Props = {
  value: string | number;
  options: Option[];
  onChange: (value: string | number) => void;
  ariaLabel?: string;
  disabled?: boolean;
};

function SimpleSelect({ value, options, onChange, ariaLabel, disabled = false }: Props) {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement | null>(null);

  const selectedLabel = useMemo(() => {
    const match = options.find((opt) => `${opt.value}` === `${value}`);
    return match?.label ?? "";
  }, [options, value]);

  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (ref.current && !ref.current.contains(event.target as Node)) {
        setOpen(false);
      }
    }
    function handleEscape(event: KeyboardEvent) {
      if (event.key === "Escape") setOpen(false);
    }
    document.addEventListener("mousedown", handleClickOutside);
    document.addEventListener("keydown", handleEscape);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
      document.removeEventListener("keydown", handleEscape);
    };
  }, []);

  return (
    <div className={styles.root} ref={ref}>
      <button
        type="button"
        className={`${styles.trigger} ${disabled ? styles.triggerDisabled : ""}`}
        aria-label={ariaLabel}
        aria-expanded={open}
        aria-disabled={disabled}
        onClick={() => {
          if (disabled) return;
          setOpen((prev) => !prev);
        }}
        disabled={disabled}
      >
        {selectedLabel}
      </button>

      {open && !disabled && (
        <ul className={styles.menu} role="listbox">
          {options.map((opt) => {
            const isActive = `${opt.value}` === `${value}`;
            return (
              <li key={opt.value}>
                <button
                  type="button"
                  className={`${styles.option} ${isActive ? styles.optionActive : ""}`}
                  aria-label={opt.label}
                  onClick={() => {
                    onChange(opt.value);
                    setOpen(false);
                  }}
                >
                  {opt.label}
                </button>
              </li>
            );
          })}
        </ul>
      )}
    </div>
  );
}

export default SimpleSelect;
