import React, { forwardRef, InputHTMLAttributes } from 'react';
import { clsx } from 'clsx';

export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  error?: string;
  helperText?: string;
  isRequired?: boolean;
  isInvalid?: boolean;
  isValid?: boolean;
  size?: 'sm' | 'md' | 'lg';
  variant?: 'outline' | 'filled' | 'unstyled';
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  leftAddon?: React.ReactNode;
  rightAddon?: React.ReactNode;
  onLeftIconClick?: () => void;
  onRightIconClick?: () => void;
}

const Input = forwardRef<HTMLInputElement, InputProps>(({
  label,
  error,
  helperText,
  isRequired = false,
  isInvalid = false,
  isValid = false,
  size = 'md',
  variant = 'outline',
  leftIcon,
  rightIcon,
  leftAddon,
  rightAddon,
  className,
  id,
  onRightIconClick,
  onLeftIconClick,
  disabled,
  ...props
}, ref) => {
  const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
  const hasError = isInvalid || !!error;
  const hasSuccess = isValid && !hasError;

  const baseInputClasses = [
    'w-full transition-colors duration-200',
    'focus:outline-none',
    'disabled:opacity-50 disabled:cursor-not-allowed',
    'placeholder:text-[var(--text-tertiary)]'
  ];

  const variantClasses = {
    outline: [
      'bg-[var(--bg-primary)] border border-[var(--border-secondary)]',
      'focus:border-[var(--color-primary)] focus:ring-1 focus:ring-[var(--color-primary)]',
      hasError ? 'border-[var(--color-error)] focus:border-[var(--color-error)] focus:ring-[var(--color-error)]' : '',
      hasSuccess ? 'border-[var(--color-success)] focus:border-[var(--color-success)] focus:ring-[var(--color-success)]' : ''
    ],
    filled: [
      'bg-[var(--bg-secondary)] border border-transparent',
      'focus:bg-[var(--bg-primary)] focus:border-[var(--color-primary)]',
      hasError ? 'border-[var(--color-error)]' : '',
      hasSuccess ? 'border-[var(--color-success)]' : ''
    ],
    unstyled: [
      'bg-transparent border-none',
      'focus:ring-0'
    ]
  };

  const sizeClasses = {
    sm: leftIcon || rightIcon ? 'h-8 px-8 text-sm' : 'h-8 px-3 text-sm',
    md: leftIcon || rightIcon ? 'h-10 px-10 text-base' : 'h-10 px-4 text-base',
    lg: leftIcon || rightIcon ? 'h-12 px-12 text-lg' : 'h-12 px-5 text-lg'
  };

  const iconSizeClasses = {
    sm: 'w-4 h-4',
    md: 'w-5 h-5',
    lg: 'w-6 h-6'
  };

  const inputClasses = clsx(
    baseInputClasses,
    variantClasses[variant],
    sizeClasses[size],
    'rounded-lg',
    {
      'pl-8': leftIcon && size === 'sm',
      'pl-10': leftIcon && size === 'md',
      'pl-12': leftIcon && size === 'lg',
      'pr-8': rightIcon && size === 'sm',
      'pr-10': rightIcon && size === 'md',
      'pr-12': rightIcon && size === 'lg',
      'rounded-l-none': leftAddon,
      'rounded-r-none': rightAddon,
    },
    className
  );

  const addonClasses = clsx(
    'inline-flex items-center px-3 text-sm bg-[var(--bg-tertiary)] border border-[var(--border-secondary)] text-[var(--text-secondary)]',
    {
      'border-r-0 rounded-l-lg': leftAddon,
      'border-l-0 rounded-r-lg': rightAddon,
    }
  );

  const leftIconClasses = clsx(
    'absolute text-[var(--text-tertiary)] pointer-events-none',
    iconSizeClasses[size],
    {
      'left-2': size === 'sm',
      'left-2.5': size === 'md',
      'left-3': size === 'lg',
      'top-1/2 -translate-y-1/2': true,
    }
  );

  const rightIconClasses = clsx(
    'absolute text-[var(--text-tertiary)]',
    iconSizeClasses[size],
    {
      'right-2': size === 'sm',
      'right-2.5': size === 'md', 
      'right-3': size === 'lg',
      'top-1/2 -translate-y-1/2': true,
    }
  );

  const inputElement = (
    <div className="relative">
      {leftIcon && (
        <button
          type="button"
          onClick={onLeftIconClick}
          className={clsx(leftIconClasses, 'cursor-pointer hover:text-[var(--text-primary)]')}
          disabled={disabled}
        >
          {leftIcon}
        </button>
      )}
      <input
        ref={ref}
        id={inputId}
        className={inputClasses}
        aria-invalid={hasError}
        aria-describedby={
          error ? `${inputId}-error` : 
          helperText ? `${inputId}-helper` : 
          undefined
        }
        {...props}
      />
      {rightIcon && (
        <button
          type="button"
          onClick={onRightIconClick}
          className={clsx(rightIconClasses, 'cursor-pointer hover:text-[var(--text-primary)]')}
          disabled={disabled}
        >
          {rightIcon}
        </button>
      )}
    </div>
  );

  const inputWithAddons = (
    <div className="flex">
      {leftAddon && (
        <span className={addonClasses}>{leftAddon}</span>
      )}
      {inputElement}
      {rightAddon && (
        <span className={addonClasses}>{rightAddon}</span>
      )}
    </div>
  );

  return (
    <div className="w-full">
      {label && (
        <label 
          htmlFor={inputId}
          className="block text-sm font-medium text-[var(--text-primary)] mb-2"
        >
          {label}
          {isRequired && (
            <span className="text-[var(--color-error)] ml-1">*</span>
          )}
        </label>
      )}
      
      {leftAddon || rightAddon ? inputWithAddons : inputElement}
      
      {error && (
        <p 
          id={`${inputId}-error`}
          className="mt-2 text-sm text-[var(--color-error)]"
        >
          {error}
        </p>
      )}
      
      {helperText && !error && (
        <p 
          id={`${inputId}-helper`}
          className="mt-2 text-sm text-[var(--text-secondary)]"
        >
          {helperText}
        </p>
      )}
    </div>
  );
});

Input.displayName = 'Input';

export default Input;