import { useEffect, useRef } from 'react';
import { IconFilter, IconArrowDown } from '../icons';
import { MenuSelect, type MenuSelectItem } from '../MenuSelect';
import styles from './SelectFilter.module.scss';

export type SelectFilterSize = 'regular' | 'large';

export interface SelectFilterProps {
  /** Label displayed in the trigger button */
  label: string;
  /** Array of selectable items */
  items: MenuSelectItem[];
  /** Currently selected value */
  value?: string | null;
  /** Callback when selection changes */
  onChange?: (value: string) => void;
  /** Whether the dropdown is open (controlled) */
  isOpen: boolean;
  /** Callback when open state changes */
  onOpenChange: (isOpen: boolean) => void;
  /** Size variant - 'regular' (38px) or 'large' (52px) */
  size?: SelectFilterSize;
  /** Maximum height for dropdown before scrolling (default: 240px) */
  maxHeight?: number;
  /** Enable type-to-filter input inside the dropdown */
  filterable?: boolean;
  /** Show the selection count badge (default: true) */
  showBadge?: boolean;
  /** Additional CSS classes */
  className?: string;
}

export const SelectFilter = ({
  label,
  items,
  value,
  onChange,
  isOpen,
  onOpenChange,
  size = 'regular',
  maxHeight = 240,
  filterable = false,
  showBadge = true,
  className = '',
}: SelectFilterProps) => {
  const containerRef = useRef<HTMLDivElement>(null);

  const selectedCount = value ? 1 : 0;

  useEffect(() => {
    if (!isOpen) return;

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

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

  useEffect(() => {
    if (!isOpen) return;

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        onOpenChange(false);
      }
    };

    document.addEventListener('keydown', handleEscape);
    return () => document.removeEventListener('keydown', handleEscape);
  }, [isOpen, onOpenChange]);

  const handleTriggerClick = () => {
    onOpenChange(!isOpen);
  };

  const handleSelect = (selectedValue: string) => {
    onChange?.(selectedValue);
    onOpenChange(false);
  };

  const containerClassName = [styles.container, className].filter(Boolean).join(' ');
  const triggerClassName = [
    styles.trigger,
    styles[size],
    isOpen && styles.open,
  ].filter(Boolean).join(' ');
  const dropdownClassName = [
    styles.dropdown,
    styles[`dropdown${size.charAt(0).toUpperCase() + size.slice(1)}`],
  ].join(' ');

  return (
    <div className={containerClassName} ref={containerRef}>
      <button
        type="button"
        className={triggerClassName}
        onClick={handleTriggerClick}
        aria-haspopup="listbox"
        aria-expanded={isOpen}
      >
        <IconFilter size={16} className={styles.filterIcon} />
        <span className={styles.label}>{label}</span>
        <IconArrowDown size={16} className={styles.arrowIcon} />
        {showBadge && selectedCount > 0 && (
          <span className={styles.badge}>{selectedCount}</span>
        )}
      </button>

      {isOpen && (
        <div className={dropdownClassName}>
          <MenuSelect
            items={items}
            value={value}
            onChange={handleSelect}
            maxHeight={maxHeight}
            filterable={filterable}
          />
        </div>
      )}
    </div>
  );
};
