import * as React from 'react';
import { Search as SearchIcon, X } from 'lucide-react';
import { cn } from '../../shared/utils';

export interface SearchProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
  onSearch?: (value: string) => void;
  onClear?: () => void;
  containerClassName?: string;
  /**
   * Size variant — matches the Input component sizing scale.
   * - `sm`: h-8 (32px), text-sm
   * - `md`: h-10 (40px), text-base — **default**, aligned with Input default
   * - `lg`: h-12 (48px), text-base
   */
  size?: 'sm' | 'md' | 'lg';
  /** Accessible label for the search icon / input. @default "Search" */
  searchLabel?: string;
  /** Accessible label for the clear button. @default "Clear search" */
  clearLabel?: string;
}

/**
 * Pre-built search input with integrated icon and clear button.
 *
 * @description
 * An input optimized for search interactions with a built-in magnifying glass icon,
 * clear button (Escape key or X icon), and consistent styling.
 * Supports the same size scale as Input (`sm`, `md`, `lg`) for consistent form alignment.
 *
 * @ai-rules
 * 1. Use for global or local list/table search — prefer this over raw `<Input>` for search features.
 * 2. Use `onSearch` to react to value changes, or `onClear` when the user clears the input.
 * 3. For a command palette (Cmd+K), use `<Command>` instead.
 */
const Search = React.forwardRef<HTMLInputElement, SearchProps>(
  (
    {
      className,
      containerClassName,
      onSearch,
      onClear,
      onChange,
      size = 'md',
      searchLabel = 'Search',
      clearLabel = 'Clear search',
      value: controlledValue,
      defaultValue,
      ...props
    },
    ref
  ) => {
    const isControlled = controlledValue !== undefined;
    const [internalValue, setInternalValue] = React.useState<string>(
      isControlled ? '' : ((defaultValue as string) ?? '')
    );
    const displayValue = isControlled ? (controlledValue as string) : internalValue;

    const sizeClasses = {
      sm: 'h-8 px-8 py-1 text-sm',
      md: 'h-10 px-10 py-2 text-base',
      lg: 'h-12 px-12 py-3 text-base',
    };

    const iconSizeClasses = {
      sm: 'left-2 h-3.5 w-3.5',
      md: 'left-3 h-4 w-4',
      lg: 'left-4 h-5 w-5',
    };

    const clearSizeClasses = {
      sm: 'right-2',
      md: 'right-3',
      lg: 'right-4',
    };

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const newValue = e.target.value;
      if (!isControlled) setInternalValue(newValue);
      onChange?.(e);
      onSearch?.(newValue);
    };

    const handleClear = () => {
      if (!isControlled) setInternalValue('');
      onClear?.();
      onSearch?.('');
    };

    const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
      if (e.key === 'Escape') {
        handleClear();
      }
      props.onKeyDown?.(e);
    };

    return (
      <div className={cn('relative w-full', containerClassName)}>
        <SearchIcon
          aria-hidden="true"
          className={cn(
            'absolute top-1/2 -translate-y-1/2 text-muted-foreground',
            iconSizeClasses[size]
          )}
        />
        <input
          ref={ref}
          type="text"
          value={displayValue}
          onChange={handleChange}
          onKeyDown={handleKeyDown}
          className={cn(
            'flex w-full rounded-[var(--radius)] border border-input-stroke bg-background text-foreground transition-colors outline-none',
            'placeholder:text-muted-foreground',
            'focus:ring-2 focus:ring-primary focus:border-transparent',
            'disabled:cursor-not-allowed disabled:opacity-50',
            sizeClasses[size],
            className
          )}
          aria-label={props.placeholder || searchLabel}
          {...props}
        />
        {displayValue && (
          <button
            type="button"
            onClick={handleClear}
            aria-label={clearLabel}
            className={cn(
              'absolute top-1/2 -translate-y-1/2 text-muted-foreground transition-colors hover:text-foreground focus:outline-none',
              clearSizeClasses[size]
            )}
          >
            <X className="h-4 w-4" />
          </button>
        )}
      </div>
    );
  }
);
Search.displayName = 'Search';

export { Search };
