'use client';

import { CSSProperties, useState, useRef, useEffect } from 'react';
import { cn } from '@/utils/helpers';
import styles from './Select.module.scss';

export interface SelectOption<T = string> {
  label: string;
  value: T;
  disabled?: boolean;
}

export interface SelectProps<T = string> {
  options: SelectOption<T>[];
  value?: T;
  onChange?: (value: T) => void;
  placeholder?: string;
  disabled?: boolean;
  searchable?: boolean;
  size?: 'sm' | 'md' | 'lg';
  error?: string;
  label?: string;
  className?: string;
  style?: CSSProperties;
}

export function Select<T extends string | number>({
  options,
  value,
  onChange,
  placeholder = '请选择',
  disabled = false,
  searchable = false,
  size = 'md',
  error,
  label,
  className,
  style,
}: SelectProps<T>) {
  const [isOpen, setIsOpen] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const selectRef = useRef<HTMLDivElement>(null);

  const selectedOption = options.find((opt) => opt.value === value);

  const filteredOptions = searchable
    ? options.filter((opt) => opt.label.toLowerCase().includes(searchTerm.toLowerCase()))
    : options;

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (selectRef.current && !selectRef.current.contains(event.target as Node)) {
        setIsOpen(false);
        setSearchTerm('');
      }
    };

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

  const handleSelect = (option: SelectOption<T>) => {
    if (option.disabled) return;
    onChange?.(option.value);
    setIsOpen(false);
    setSearchTerm('');
  };

  return (
    <div className={cn(styles.selectWrapper, className)} ref={selectRef} style={style}>
      {label && <label className={styles.selectWrapper__label}>{label}</label>}
      <div
        className={cn(
          styles.select,
          styles[`select--${size}`],
          isOpen && styles['select--open'],
          disabled && styles['select--disabled'],
          error && styles['select--error']
        )}
        onClick={() => !disabled && setIsOpen(!isOpen)}
      >
        <div className={styles.select__value}>
          {searchable && isOpen ? (
            <input
              type="text"
              className={styles.select__search}
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              placeholder={selectedOption?.label || placeholder}
              onClick={(e) => e.stopPropagation()}
              autoFocus
            />
          ) : (
            <span className={cn(!selectedOption && styles['select__value--placeholder'])}>
              {selectedOption?.label || placeholder}
            </span>
          )}
        </div>
        <span className={cn(styles.select__arrow, isOpen && styles['select__arrow--open'])}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </span>
      </div>
      {isOpen && (
        <div className={styles.select__dropdown}>
          {filteredOptions.length === 0 ? (
            <div className={styles.select__empty}>无匹配选项</div>
          ) : (
            filteredOptions.map((option) => (
              <div
                key={String(option.value)}
                className={cn(
                  styles.select__option,
                  option.value === value && styles['select__option--selected'],
                  option.disabled && styles['select__option--disabled']
                )}
                onClick={() => handleSelect(option)}
              >
                {option.label}
              </div>
            ))
          )}
        </div>
      )}
      {error && <span className={styles.selectWrapper__error}>{error}</span>}
    </div>
  );
}
