import React, { useEffect, useRef, useState } from 'react';
import { SortByType, SortingOption } from '../../types';
import { PickerItem } from '../../../shared/types';

interface ItemPickerProps {
  items: PickerItem[] | SortByType[] | SortingOption[];
  selection: string | undefined;
  selectedSortByType?: SortByType | null;
  label: string;
  placeholder: string;
  classModifier: string;
  valueFormatter?: (value: string, direction?: string) => string;
  onPick: (picked: string, direction?: string) => void;
}

const ItemPicker: React.FC<ItemPickerProps> = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
  const [openDirection, setOpenDirection] = useState<'down' | 'up'>('down');
  const dropdownRef = useRef<HTMLDivElement | null>(null);
  const dropdownMenuRef = useRef<HTMLUListElement | null>(null);
  const toggleButtonRef = useRef<HTMLButtonElement | null>(null);

  const handlePick = (picked: string, direction?: string) => {
    setIsDropdownOpen(false);
    onPick(picked, direction);
  };

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
        setIsDropdownOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, []);

  useEffect(() => {
    if (isDropdownOpen && toggleButtonRef.current) {
      const buttonRect = toggleButtonRef.current.getBoundingClientRect();
      const spaceBelow = window.innerHeight - buttonRect.bottom;
      const spaceAbove = buttonRect.top;
      const dropdownHeight = dropdownMenuRef.current?.offsetHeight ?? 16;
      setOpenDirection(spaceBelow < dropdownHeight && spaceAbove > spaceBelow ? 'up' : 'down');
    }
  }, [isDropdownOpen]);

  return (
    <div className={'dropdown__input ' + classModifier}>
      <span className="dropdown__label">{label}</span>
      <div className="dropdown" ref={dropdownRef}>
        <button
          type="button"
          className={`dropdown-toggle ${isDropdownOpen ? 'dropdown-toggle--open' : ''}`}
          onClick={() => setIsDropdownOpen((prev) => !prev)}
          ref={toggleButtonRef}>
          <span>{selectedSortByType ? valueFormatter?.(selectedSortByType.label, selectedSortByType?.direction) : selection || placeholder}</span>
          <span className="arrow">&#9662;</span>
        </button>
        {isDropdownOpen && (
          <ul className={`dropdown-menu dropdown-menu--${openDirection}`} ref={dropdownMenuRef}>
            {items.map((item, index) => (
              <li
                key={`${item.label}-${index}`}
                onClick={() => handlePick(item.label, 'direction' in item ? item.direction : undefined)}
                className={`dropdown-menu__item${selection === item.label ? ' dropdown-menu__item--selected' : ''}`}>
                {item.icon && <span className="travel-class-icon">{item.icon}</span>}
                {valueFormatter ? valueFormatter(item.label, 'direction' in item ? item.direction : undefined) : item.label}
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
};

export default ItemPicker;
