import React, { useState, useRef, useEffect } from 'react';

const MultiSelectDropdown = ({ 
  value = [], 
  onChange, 
  options = [], 
  placeholder = 'Select...', 
  exclusiveOptionValue = null,
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [search, setSearch] = useState('');
  const containerRef = useRef(null);

  useEffect(() => {
    const handleClickOutside = (e) => {
      if (containerRef.current && !containerRef.current.contains(e.target)) {
        setIsOpen(false);
        setSearch('');
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  // Flatten grouped options into a flat list for filtering/selection
  const flatOptions = options.reduce((acc, opt) => {
    if (opt.options) {
      return [...acc, ...opt.options];
    }
    return [...acc, opt];
  }, []);

  const selectedValues = (value || []).map(v => v.value);
  const hasExclusiveSelected = !!exclusiveOptionValue && selectedValues.includes(exclusiveOptionValue);

  const filteredOptions = search
    ? flatOptions.filter(opt => opt.label.toLowerCase().includes(search.toLowerCase()))
    : flatOptions;

  const isOptionDisabled = (opt) => (
    hasExclusiveSelected && opt.value !== exclusiveOptionValue
  );
  const selectableFilteredOptions = filteredOptions.filter(opt => !isOptionDisabled(opt));
  const allFilteredSelected = selectableFilteredOptions.length > 0
    && selectableFilteredOptions.every(opt => selectedValues.includes(opt.value));

  const toggleOption = (opt) => {
    if (isOptionDisabled(opt)) {
      return;
    }
    const exists = selectedValues.includes(opt.value);
    if (exists) {
      onChange(value.filter(v => v.value !== opt.value));
    } else {
      if (exclusiveOptionValue && opt.value === exclusiveOptionValue) {
        onChange([opt]);
        return;
      }
      onChange([...value, opt]);
    }
  };

  const toggleSelectAll = () => {
    if (allFilteredSelected) {
      const filteredValues = selectableFilteredOptions.map(o => o.value);
      onChange(value.filter(v => !filteredValues.includes(v.value)));
    } else {
      const currentValues = new Set(selectedValues);
      const newItems = selectableFilteredOptions.filter(o => !currentValues.has(o.value));
      onChange([...value, ...newItems]);
    }
  };

  const removeItem = (e, opt) => {
    e.stopPropagation();
    onChange(value.filter(v => v.value !== opt.value));
  };

  return (
    <div className="multi-select-dropdown" ref={containerRef}>
      <div 
        className={`multi-select-dropdown__control ${isOpen ? 'multi-select-dropdown__control--open' : ''}`}
        onClick={() => setIsOpen(!isOpen)}
      >
        <div className="multi-select-dropdown__value-container">
          {value.length === 0 ? (
            <span className="multi-select-dropdown__placeholder">{placeholder}</span>
          ) : (
            <div className="multi-select-dropdown__tags">
              {value.map((v) => (
                <span key={v.value} className="multi-select-dropdown__tag">
                  {v.label}
                  <span className="multi-select-dropdown__tag-remove" onClick={(e) => removeItem(e, v)}>&times;</span>
                </span>
              ))}
            </div>
          )}
        </div>
        <div className="multi-select-dropdown__indicator">
          <svg width="16" height="16" viewBox="0 0 20 20" style={{ transform: isOpen ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}>
            <path d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z" fill="#999" />
          </svg>
        </div>
      </div>

      {isOpen && (
        <div className="multi-select-dropdown__menu">
          <div className="multi-select-dropdown__search-container">
            <input
              type="text"
              className="multi-select-dropdown__search"
              placeholder="Search..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onClick={(e) => e.stopPropagation()}
              autoFocus
            />
          </div>
          <div 
            className="multi-select-dropdown__option multi-select-dropdown__select-all"
            onClick={toggleSelectAll}
          >
            <input 
              type="checkbox" 
              checked={allFilteredSelected} 
              onChange={toggleSelectAll}
              onClick={(e) => e.stopPropagation()}
              className="multi-select-dropdown__checkbox"
            />
            <span>Select All</span>
          </div>
          <div className="multi-select-dropdown__options-list">
            {filteredOptions.length === 0 && (
              <div className="multi-select-dropdown__no-options">No options found</div>
            )}
            {filteredOptions.map((opt) => (
              <div
                key={opt.value}
                className={`multi-select-dropdown__option ${selectedValues.includes(opt.value) ? 'multi-select-dropdown__option--selected' : ''} ${isOptionDisabled(opt) ? 'multi-select-dropdown__option--disabled' : ''}`}
                onClick={() => toggleOption(opt)}
                style={isOptionDisabled(opt) ? { opacity: 0.5, cursor: 'not-allowed' } : {}}
              >
                <input 
                  type="checkbox" 
                  checked={selectedValues.includes(opt.value)} 
                  onChange={() => toggleOption(opt)}
                  onClick={(e) => e.stopPropagation()}
                  className="multi-select-dropdown__checkbox"
                  disabled={isOptionDisabled(opt)}
                />
                <span>{opt.label}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default MultiSelectDropdown;
