import React, { useState, useCallback } from 'react';
import { cn } from '@/lib/utils';
import FormLabel from './FormLabel';
import FormError from './FormError';

/**
 * FormSelect Component
 * Select dropdown with placeholder, multi-select support, and custom styling
 */

export interface SelectOption {
  value: string | number;
  label: string;
  disabled?: boolean;
}

export interface FormSelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'multiple' | 'size'> {
  label?: string;
  error?: string | string[];
  helpText?: string;
  required?: boolean;
  options: SelectOption[];
  placeholder?: string;
  multiple?: boolean;
  showSearch?: boolean;
  containerClassName?: string;
  selectClassName?: string;
  onSearch?: (query: string) => void;
}

export const FormSelect: React.FC<FormSelectProps> = ({
  label,
  error,
  helpText,
  required = false,
  options,
  placeholder = 'Select an option',
  multiple = false,
  showSearch = false,
  containerClassName,
  selectClassName,
  onSearch,
  disabled = false,
  value,
  onChange,
  ...props
}) => {
  const [isFocused, setIsFocused] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');

  const hasError = !!error;
  const showError = hasError;

  const handleFocus = () => setIsFocused(true);
  const handleBlur = () => setIsFocused(false);

  const handleChange = useCallback((e: React.ChangeEvent<HTMLSelectElement>) => {
    onChange?.(e);
  }, [onChange]);

  const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const query = e.target.value;
    setSearchQuery(query);
    if (onSearch) {
      onSearch(query);
    }
  }, [onSearch]);

  const filteredOptions = showSearch && searchQuery
    ? options.filter(option => 
        option.label.toLowerCase().includes(searchQuery.toLowerCase())
      )
    : options;

  const inputId = props.id || (label ? label.toLowerCase().replace(/\s+/g, '-') : undefined);

  const baseSelectClasses = cn(
    'w-full px-3 py-2 border rounded-md transition-all duration-200',
    'bg-neutral-light text-text-primary',
    'focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary',
    'disabled:opacity-60 disabled:cursor-not-allowed',
    'appearance-none cursor-pointer',
    'bg-[length:1.5em_1.5em] bg-[position:right_0.5rem_center] bg-no-repeat',
    'bg-[url("data:image/svg+xml,%3csvg xmlns=\'http://www.w3.org/2000/svg\' fill=\'none\' viewBox=\'0 0 20 20\'%3e%3cpath stroke=\'%236c757d\' stroke-linecap=\'round\' stroke-linejoin=\'round\' stroke-width=\'1.5\' d=\'M6 8l4 4 4-4\'/%3e%3c/svg%3e")]',
    {
      'border-neutral-dark hover:border-neutral-dark': !hasError && !isFocused,
      'border-primary ring-2 ring-primary': isFocused && !hasError,
      'border-danger ring-2 ring-danger/20': hasError,
      'pr-10': !showSearch,
    },
    selectClassName
  );

  const containerClasses = cn(
    'flex flex-col gap-1.5',
    containerClassName
  );

  const searchInputClasses = cn(
    'w-full px-3 py-2 border-b border-neutral-dark bg-transparent',
    'focus:outline-none focus:border-primary',
    'placeholder:text-text-light'
  );

  // Custom dropdown arrow
  const dropdownArrow = (
    <svg
      className="w-4 h-4 text-text-secondary pointer-events-none absolute right-3 top-1/2 -translate-y-1/2"
      fill="currentColor"
      viewBox="0 0 20 20"
    >
      <path
        fillRule="evenodd"
        d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
        clipRule="evenodd"
      />
    </svg>
  );

  const renderOptions = () => {
    // Add placeholder as first option if not multiple and no value
    const showPlaceholder = !multiple && !value && placeholder;

    return (
      <>
        {showPlaceholder && (
          <option value="" disabled>
            {placeholder}
          </option>
        )}
        {filteredOptions.map((option) => (
          <option
            key={option.value}
            value={option.value}
            disabled={option.disabled}
            className={option.disabled ? 'opacity-50' : ''}
          >
            {option.label}
          </option>
        ))}
      </>
    );
  };

  return (
    <div className={containerClasses}>
      {label && (
        <FormLabel htmlFor={inputId} required={required}>
          {label}
        </FormLabel>
      )}

      <div className="relative">
        {showSearch && (
          <input
            type="text"
            placeholder="Search options..."
            value={searchQuery}
            onChange={handleSearchChange}
            className={searchInputClasses}
            disabled={disabled}
          />
        )}

        <select
          id={inputId}
          className={baseSelectClasses}
          value={value}
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          disabled={disabled}
          multiple={multiple}
          aria-invalid={hasError}
          aria-describedby={helpText || showError ? `${inputId}-error` : undefined}
          required={required}
          {...props}
        >
          {renderOptions()}
        </select>

        {!showSearch && dropdownArrow}
      </div>

      {helpText && (
        <p className="text-xs text-text-secondary" id={`${inputId}-help`}>
          {helpText}
        </p>
      )}

      {showError && (
        <FormError errors={error} id={`${inputId}-error`} />
      )}
    </div>
  );
};

FormSelect.displayName = 'FormSelect';

export default FormSelect;