import { useEffect, useRef } from "react";
import Choices from "choices.js";
import "choices.js/public/assets/styles/choices.min.css";

interface OptionType { value: string | number; label: string; }

interface CommonSearchSelectProps {
  label?: string;
  value: string | number;
  options: OptionType[];
  onChange: (value: string) => void;
  required?: boolean;
  disabled?: boolean;
}

export default function CommonSearchSelect({
  label = "", value, options, onChange, required = false, disabled = false,
}: CommonSearchSelectProps) {
  const selectRef  = useRef<HTMLSelectElement | null>(null);
  const choicesRef = useRef<Choices | null>(null);

  // FIX: store onChange in a ref so the event listener closure never goes stale
  // and doesn't need to be in useEffect's dependency array
  const onChangeRef = useRef(onChange);
  useEffect(() => { onChangeRef.current = onChange; }, [onChange]);

  useEffect(() => {
    if (!selectRef.current) return;
    choicesRef.current = new Choices(selectRef.current, {
      searchEnabled: true,
      removeItemButton: false,
      shouldSort: false,
      placeholderValue: `Select ${label.toLowerCase()}...`,
      allowHTML: false,
    });

    // FIX: store handler reference so it can be removed in cleanup
    // Original called addEventListener but never removeEventListener → memory leak
    const handler = (e: Event) => {
      onChangeRef.current((e.target as HTMLSelectElement).value);
    };
    selectRef.current.addEventListener("change", handler);

    return () => {
      selectRef.current?.removeEventListener("change", handler);
      choicesRef.current?.destroy();
    };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (!choicesRef.current) return;
    const instance = choicesRef.current;
    instance.clearChoices();
    instance.setChoices(
      [
        { value: "", label: `Select one`, disabled: false, selected: !value, placeholder: true },
        ...options.map((o) => ({ value: o.value, label: o.label, selected: o.value === value })),
      ],
      "value", "label", true
    );
    if (value) instance.setChoiceByValue(String(value));
    if (disabled) { instance.disable(); } else { instance.enable(); }
  }, [options, value, disabled]);

  return (
    <>
      <label>{label}</label>
      <select ref={selectRef} hidden required={required} />
    </>
  );
}
