import { useEffect, useMemo, useRef, useState } from 'react';
import { Check, ChevronDown, Search, X } from 'lucide-react';

export default function MultiSelectDropdown({
  options,
  value = [],
  onChange,
  placeholder = 'انتخاب کنید',
  searchPlaceholder = 'جست‌وجوی اعضا...',
  disabled = false,
}) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');
  const rootRef = useRef(null);
  const searchRef = useRef(null);
  const selectedIds = useMemo(() => new Set(value.map(Number)), [value]);
  const selectedOptions = options.filter((option) => selectedIds.has(Number(option.value)));
  const filteredOptions = options.filter((option) => option.label.toLocaleLowerCase('fa').includes(query.trim().toLocaleLowerCase('fa')));

  useEffect(() => {
    if (!open) return undefined;
    const dismiss = (event) => {
      if (event.key === 'Escape' || (event.type === 'pointerdown' && !rootRef.current?.contains(event.target))) {
        setOpen(false);
      }
    };
    document.addEventListener('pointerdown', dismiss);
    document.addEventListener('keydown', dismiss);
    requestAnimationFrame(() => searchRef.current?.focus());
    return () => {
      document.removeEventListener('pointerdown', dismiss);
      document.removeEventListener('keydown', dismiss);
    };
  }, [open]);

  const toggle = (optionValue) => {
    const id = Number(optionValue);
    onChange(selectedIds.has(id) ? value.filter((item) => Number(item) !== id) : [...value, id]);
  };

  const remove = (event, optionValue) => {
    event.stopPropagation();
    onChange(value.filter((item) => Number(item) !== Number(optionValue)));
  };

  return (
    <div className={`multi-select${open ? ' open' : ''}`} ref={rootRef}>
      <button
        type="button"
        className="multi-select-trigger"
        onClick={() => !disabled && setOpen((current) => !current)}
        aria-haspopup="listbox"
        aria-expanded={open}
        disabled={disabled}
      >
        <span className="multi-select-value">
          {selectedOptions.length === 0 ? <span className="multi-select-placeholder">{placeholder}</span> : selectedOptions.map((option) => (
            <span className="multi-select-chip" key={option.value}>
              {option.label}
              <X size={13} role="button" aria-label={`حذف ${option.label}`} onClick={(event) => remove(event, option.value)} />
            </span>
          ))}
        </span>
        <ChevronDown className="multi-select-chevron" size={18} />
      </button>

      {open && (
        <div className="multi-select-menu">
          <label className="multi-select-search">
            <Search size={16} />
            <input ref={searchRef} value={query} onChange={(event) => setQuery(event.target.value)} placeholder={searchPlaceholder} />
          </label>
          <div className="multi-select-options" role="listbox" aria-multiselectable="true">
            {filteredOptions.length === 0 ? <div className="multi-select-empty">عضوی یافت نشد</div> : filteredOptions.map((option) => {
              const selected = selectedIds.has(Number(option.value));
              return (
                <button
                  type="button"
                  role="option"
                  aria-selected={selected}
                  className={selected ? 'selected' : ''}
                  key={option.value}
                  onClick={() => toggle(option.value)}
                >
                  <span>{option.label}</span>
                  <span className="multi-select-check">{selected && <Check size={15} />}</span>
                </button>
              );
            })}
          </div>
          {selectedOptions.length > 0 && (
            <button type="button" className="multi-select-clear" onClick={() => onChange([])}>پاک‌کردن همه انتخاب‌ها</button>
          )}
        </div>
      )}
    </div>
  );
}
