import React, { useState, useRef, useEffect } from 'react';
import { cn } from '@/lib/utils';
import { ChevronDown, Check } from 'lucide-react';

export interface CustomSelectOption {
  value: string;
  label: string;
}

interface CustomSelectProps {
  options: CustomSelectOption[];
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  className?: string;
  triggerClassName?: string;
  dropdownClassName?: string;
  disabled?: boolean;
}

export const CustomSelect: React.FC<CustomSelectProps> = ({
  options,
  value,
  onChange,
  placeholder = "Select an option",
  className = "",
  triggerClassName = "",
  dropdownClassName = "",
  disabled = false,
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);

  // Get the selected option label
  const selectedOption = options.find(option => option.value === value);
  const displayValue = selectedOption ? selectedOption.label : placeholder;

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    const handleTouchStart = (event: TouchEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
      document.addEventListener('touchstart', handleTouchStart, { passive: true });
    }
    
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
      document.removeEventListener('touchstart', handleTouchStart);
    };
  }, [isOpen]);

  // Handle keyboard navigation
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (!isOpen) return;
      
      if (e.key === 'Escape') {
        setIsOpen(false);
      } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
        e.preventDefault();
        const currentIndex = options.findIndex(option => option.value === value);
        let newIndex = currentIndex;
        
        if (e.key === 'ArrowDown') {
          newIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0;
        } else {
          newIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1;
        }
        
        onChange(options[newIndex].value);
      }
    };
    
    if (isOpen) {
      window.addEventListener('keydown', handleKeyDown);
    }
    
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, [isOpen, options, value, onChange]);

  // Handle scroll locking when dropdown is open
  useEffect(() => {
    if (isOpen && dropdownRef.current) {
      // Scroll selected item into view
      const selectedItem = dropdownRef.current.querySelector('[aria-selected="true"]');
      if (selectedItem) {
        selectedItem.scrollIntoView({ block: 'nearest' });
      }
    }
  }, [isOpen, value]);

  // Toggle dropdown
  const handleToggle = (e: React.MouseEvent<HTMLDivElement>) => {
    e.stopPropagation();
    if (!disabled) {
      setIsOpen(!isOpen);
    }
  };

  // Select an option
  const handleSelect = (optionValue: string, e: React.MouseEvent) => {
    e.stopPropagation();
    e.preventDefault();
    onChange(optionValue);
    setIsOpen(false);
  };

  return (
    <div 
      ref={containerRef}
      className={cn(
        "relative inline-block w-full",
        className
      )}
    >
      {/* Trigger button */}
      <div
        className={cn(
          "flex items-center justify-between w-full px-3 py-2 text-sm border rounded-md cursor-pointer select-none",
          "bg-background border-input",
          disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-accent/10",
          triggerClassName
        )}
        onClick={handleToggle}
        onTouchEnd={(e) => {
          e.stopPropagation();
          if (!disabled) {
            setIsOpen(!isOpen);
          }
        }}
        aria-haspopup="listbox"
        aria-expanded={isOpen}
        role="combobox"
        tabIndex={0}
      >
        <span className="truncate">{displayValue}</span>
        <ChevronDown className={cn("h-4 w-4 transition-transform duration-200", isOpen && "transform rotate-180")} />
      </div>

      {/* Dropdown menu */}
      {isOpen && (
        <div
          ref={dropdownRef}
          className={cn(
            "absolute z-[9999] w-full mt-1 bg-popover border border-border rounded-md shadow-md max-h-60 overflow-auto",
            "animate-in fade-in-0 zoom-in-95",
            dropdownClassName
          )}
          role="listbox"
          aria-orientation="vertical"
          style={{ 
            transformOrigin: 'top',
            boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
          }}
        >
          <div className="py-1">
            {options.map((option) => (
              <div
                key={option.value}
                className={cn(
                  "flex items-center px-3 py-1.5 text-sm cursor-pointer select-none",
                  option.value === value
                    ? "bg-primary/10 text-primary font-medium"
                    : "text-foreground hover:bg-primary/5 hover:text-primary"
                )}
                role="option"
                aria-selected={option.value === value}
                tabIndex={-1}
                onClick={(e) => handleSelect(option.value, e)}
                onTouchEnd={(e) => {
                  e.stopPropagation();
                  handleSelect(option.value, e as any);
                }}
              >
                <span className="flex-grow truncate">{option.label}</span>
                {option.value === value && (
                  <Check className="h-4 w-4 ml-2 shrink-0 text-primary" />
                )}
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}; 