import React, { useState, useRef, useEffect } from 'react';
import { IconType } from 'react-icons';
import { IoChevronDown, IoClose } from 'react-icons/io5';
import styles from './DropdownSelect.module.css';
import { ButtonVariant, ButtonSize } from '../Button/ButtonTypes';

export interface DropdownSelectItem<T = any> {
  id: string | number;
  label: string;
  value: T;
  metadata?: Record<string, any>; // Additional data for custom rendering
}

export interface DropdownSelectProps<T = any> {
  items: DropdownSelectItem<T>[];
  selectedItemId?: string | number | null;
  onSelect: (item: DropdownSelectItem<T> | null) => void;
  placeholder?: string;
  emptyMessage?: string;
  headerText?: string;
  variant?: ButtonVariant;
  size?: ButtonSize;
  icon?: IconType;
  disabled?: boolean;
  loading?: boolean;
  className?: string;
  renderItem?: (item: DropdownSelectItem<T>, isSelected: boolean) => React.ReactNode;
  renderButton?: (selectedItem: DropdownSelectItem<T> | null, isOpen: boolean) => React.ReactNode;
  renderClearButton?: (selectedItem: DropdownSelectItem<T>, onClear: () => void) => React.ReactNode;
  minWidth?: string;
  maxHeight?: string;
  showClearButton?: boolean; // Enable/disable clear button feature
  clearButtonLabel?: string; // Label for clear button (defaults to showing selected item name)
}

function DropdownSelect<T = any>({
  items = [],
  selectedItemId,
  onSelect,
  placeholder = 'Select an item',
  emptyMessage = 'No items available',
  headerText,
  variant = 'primary',
  size = 'md',
  icon: Icon,
  disabled = false,
  loading = false,
  className = '',
  renderItem,
  renderButton,
  renderClearButton,
  minWidth = '180px',
  maxHeight = '300px',
  showClearButton = true,
  clearButtonLabel
}: DropdownSelectProps<T>) {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef<HTMLDivElement>(null);

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

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
    }

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

  // Find selected item
  const selectedItem = selectedItemId !== null && selectedItemId !== undefined
    ? items.find(item => item.id === selectedItemId) || null
    : null;

  // Handle item selection
  const handleItemClick = (item: DropdownSelectItem<T>) => {
    onSelect(item);
    setIsOpen(false);
  };

  // Handle clear selection
  const handleClear = () => {
    if (!disabled && !loading) {
      onSelect(null);
      setIsOpen(false);
    }
  };

  // Toggle dropdown
  const toggleDropdown = () => {
    if (!disabled && !loading) {
      setIsOpen(!isOpen);
    }
  };

  // Build button classes
  const buttonClasses = [
    styles.dropdownButton,
    styles[`button${variant.charAt(0).toUpperCase() + variant.slice(1)}`],
    styles[`button${size.charAt(0).toUpperCase() + size.slice(1)}`],
    loading ? styles.loading : '',
    disabled ? styles.disabled : '',
    className
  ].filter(Boolean).join(' ');

  // Render default button content
  const renderDefaultButton = () => {
    if (loading) {
      return (
        <>
          <div className={styles.buttonSpinner} />
          <span>{placeholder}</span>
        </>
      );
    }

    if (selectedItem) {
      return (
        <>
          {Icon && <Icon className={styles.buttonIcon} />}
          <span className={styles.buttonText}>{selectedItem.label}</span>
          <IoChevronDown className={`${styles.chevronIcon} ${isOpen ? styles.chevronOpen : ''}`} />
        </>
      );
    }

    return (
      <>
        {Icon && <Icon className={styles.buttonIcon} />}
        <span className={styles.buttonText}>{placeholder}</span>
        <IoChevronDown className={`${styles.chevronIcon} ${isOpen ? styles.chevronOpen : ''}`} />
      </>
    );
  };

  // Render clear button when item is selected and showClearButton is true
  const renderClearButtonContent = () => {
    if (renderClearButton && selectedItem) {
      return renderClearButton(selectedItem, handleClear);
    }

    if (selectedItem && showClearButton) {
      return (
        <button
          type="button"
          className={buttonClasses}
          onClick={handleClear}
          disabled={disabled || loading}
          title={clearButtonLabel || `Clear selection: ${selectedItem.label}`}
        >
          {Icon && <Icon className={styles.buttonIcon} />}
          <span className={styles.buttonText}>
            {clearButtonLabel || selectedItem.label}
          </span>
          <IoClose className={styles.clearIcon} />
        </button>
      );
    }

    return null;
  };

  return (
    <div ref={dropdownRef} className={styles.dropdownContainer} style={{ minWidth }}>
      {/* Show clear button if item is selected and showClearButton is enabled */}
      {selectedItem && showClearButton ? (
        renderClearButtonContent()
      ) : renderButton ? (
        <div className={buttonClasses} onClick={toggleDropdown}>
          {renderButton(selectedItem, isOpen)}
        </div>
      ) : (
        <button
          type="button"
          className={buttonClasses}
          onClick={toggleDropdown}
          disabled={disabled || loading}
        >
          {renderDefaultButton()}
        </button>
      )}

      {isOpen && (
        <div className={styles.dropdownMenu} style={{ maxHeight }}>
          {headerText && (
            <div className={styles.dropdownHeader}>
              {headerText}
            </div>
          )}
          
          {items.length === 0 ? (
            <div className={styles.dropdownEmpty}>
              {emptyMessage}
            </div>
          ) : (
            <div className={styles.dropdownItems}>
              {items.map((item) => {
                const isSelected = selectedItemId === item.id;
                
                if (renderItem) {
                  return (
                    <div
                      key={item.id}
                      className={`${styles.dropdownItem} ${isSelected ? styles.dropdownItemSelected : ''}`}
                      onClick={() => handleItemClick(item)}
                    >
                      {renderItem(item, isSelected)}
                    </div>
                  );
                }

                return (
                  <button
                    key={item.id}
                    type="button"
                    className={`${styles.dropdownItem} ${isSelected ? styles.dropdownItemSelected : ''}`}
                    onClick={() => handleItemClick(item)}
                  >
                    <span className={styles.itemLabel}>{item.label}</span>
                    {isSelected && <span className={styles.selectedIndicator}>✓</span>}
                  </button>
                );
              })}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

export default DropdownSelect;

