// File: src/components/UIX/Input/Input.jsx
// Input Component - Performance Optimized

import React, { useMemo, useCallback, memo } from "react";
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
import { useUIXTheme } from "../themes/useUIXTheme.jsx";

// Static size configurations - moved outside component to prevent recreation
const SIZE_CLASSES = Object.freeze({
  sm: "px-3 py-2 text-sm",
  md: "px-4 py-3 text-base",
  lg: "px-5 py-4 text-base sm:text-lg",
});

const LABEL_SIZE_CLASSES = Object.freeze({
  sm: "text-sm",
  md: "text-base",
  lg: "text-base sm:text-lg",
});

/**
 * Input Component - Performance Optimized
 * Text input field with label, validation, and icon support
 *
 * @param {string} label - Input label
 * @param {string} type - Input type (text, email, password, etc.)
 * @param {string} placeholder - Placeholder text
 * @param {string} value - Input value
 * @param {function} onChange - Change handler (receives the input value directly, NOT the event)
 * @param {string} error - Error message
 * @param {boolean} disabled - Whether input is disabled
 * @param {boolean} required - Whether input is required
 * @param {boolean} readOnly - Whether input is read-only
 * @param {React.Component} icon - Icon component to display
 * @param {string} prefix - Static text prefix to display before input (e.g., "https://")
 * @param {string} helperText - Helper text below input
 * @param {number} maxLength - Maximum character length
 * @param {boolean} showCharacterCount - Show character counter
 * @param {number} characterWarningThreshold - When to show warning color (percentage of maxLength)
 * @param {string} size - Input size (sm, md, lg)
 * @param {string} className - Additional CSS classes
 *
 * IMPORTANT: The onChange prop receives the input value directly, NOT the event object.
 * Correct usage: onChange={(value) => setMyValue(value)}
 * Incorrect usage: onChange={(e) => setMyValue(e.target.value)} // This will cause errors!
 */
const Input = memo(function Input({
  label,
  type = "text",
  placeholder,
  value = "",
  onChange,
  error,
  disabled = false,
  required = false,
  readOnly = false,
  icon: Icon,
  prefix,
  helperText,
  maxLength,
  showCharacterCount = false,
  characterWarningThreshold = 80,
  characterCountWarning,
  size = "lg",
  className = "",
  description,
  optional,
  showPasswordToggle, // Destructure to prevent passing to DOM (not implemented yet)
  ...props
}) {
  const { getThemeClasses } = useUIXTheme();

  // Generate a unique id for the input field - memoized to prevent regeneration on every render
  const inputId = useMemo(() => {
    return (
      props.id ||
      props.name ||
      `input-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    );
  }, [props.id, props.name]);

  // Memoize theme classes to prevent multiple getThemeClasses calls on each render
  const themeClasses = useMemo(
    () => ({
      textPrimary: getThemeClasses("text-primary"),
      textDanger: getThemeClasses("text-danger"),
      textMuted: getThemeClasses("text-muted"),
      textSecondary: getThemeClasses("text-secondary"),
      inputBorder: getThemeClasses("input-border"),
      inputBorderError: getThemeClasses("input-border-error"),
      inputFocusRing: getThemeClasses("input-focus-ring"),
      bgDisabled: getThemeClasses("bg-disabled"),
    }),
    [getThemeClasses]
  );

  // Memoize the onChange handler to prevent recreation on each render
  const handleChange = useCallback(
    (e) => {
      if (onChange) {
        onChange(e.target.value);
      }
    },
    [onChange]
  );

  // Memoize computed values
  const currentLength = value ? value.length : 0;
  const warningThreshold = characterCountWarning || characterWarningThreshold;
  const isNearLimit =
    maxLength && currentLength > (maxLength * warningThreshold) / 100;

  // Memoize size class lookups
  const sizeClass = SIZE_CLASSES[size] || SIZE_CLASSES.lg;
  const labelSizeClass = LABEL_SIZE_CLASSES[size] || LABEL_SIZE_CLASSES.lg;

  return (
    <div className={className}>
      {label && (
        <label
          htmlFor={inputId}
          className={`block ${labelSizeClass} font-semibold ${themeClasses.textPrimary} mb-3 flex items-center`}
        >
          {label}
          {required && (
            <span className={`ml-1 ${themeClasses.textDanger}`}>*</span>
          )}
        </label>
      )}
      <div className="relative">
        {prefix ? (
          // Input with prefix
          <div className={`
            flex items-center w-full
            border-2 rounded-xl shadow-sm
            transition-all duration-200
            ${error ? themeClasses.inputBorderError : themeClasses.inputBorder}
            ${disabled ? `${themeClasses.bgDisabled} cursor-not-allowed` : "bg-white"}
            focus-within:outline-none focus-within:${themeClasses.inputFocusRing}
          `}>
            <span className={`
              ${sizeClass}
              pr-0 font-medium
              ${disabled ? themeClasses.textMuted : themeClasses.textSecondary}
              select-none whitespace-nowrap
            `}>
              {prefix}
            </span>
            <input
              id={inputId}
              name={props.name || inputId}
              type={type}
              placeholder={placeholder}
              value={value}
              onChange={handleChange}
              disabled={disabled}
              required={required}
              readOnly={readOnly}
              maxLength={maxLength}
              className={`
                flex-1
                ${sizeClass}
                pl-0
                bg-transparent
                border-0
                focus:outline-none focus:ring-0
                placeholder-gray-400
              `}
              {...props}
            />
          </div>
        ) : (
          // Regular input without prefix
          <>
            {Icon && (
              <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                <Icon className={`h-5 w-5 ${themeClasses.textMuted}`} />
              </div>
            )}
            <input
              id={inputId}
              name={props.name || inputId}
              type={type}
              placeholder={placeholder}
              value={value}
              onChange={handleChange}
              disabled={disabled}
              required={required}
              readOnly={readOnly}
              maxLength={maxLength}
              className={`
                w-full
                ${sizeClass}
                ${Icon ? "pl-10" : "pl-5"}
                border-2 rounded-xl shadow-sm
                transition-all duration-200
                placeholder-gray-400
                focus:outline-none ${themeClasses.inputFocusRing} ${themeClasses.inputBorder}
                ${error ? themeClasses.inputBorderError : themeClasses.inputBorder}
                ${disabled ? `${themeClasses.bgDisabled} cursor-not-allowed` : "bg-white"}
              `}
              {...props}
            />
          </>
        )}
      </div>

      {/* Character count */}
      {showCharacterCount && maxLength && (
        <div className="mt-1 text-right">
          <span
            className={`text-xs ${
              isNearLimit ? "text-amber-600" : themeClasses.textMuted
            }`}
          >
            {currentLength}/{maxLength} characters
          </span>
        </div>
      )}

      {/* Helper text */}
      {helperText && !error && (
        <p className={`mt-1 text-xs ${themeClasses.textMuted}`}>
          {helperText}
        </p>
      )}

      {/* Error message */}
      {error && (
        <p
          className={`mt-1 text-sm ${themeClasses.textDanger} flex items-center animate-fade-in`}
        >
          <ExclamationTriangleIcon
            className={`h-4 w-4 mr-1 ${themeClasses.textDanger}`}
          />
          {error}
        </p>
      )}
    </div>
  );
},
// Custom comparison function for memo - only re-render when these props change
(prevProps, nextProps) => {
  return (
    prevProps.value === nextProps.value &&
    prevProps.error === nextProps.error &&
    prevProps.disabled === nextProps.disabled &&
    prevProps.label === nextProps.label &&
    prevProps.placeholder === nextProps.placeholder &&
    prevProps.type === nextProps.type &&
    prevProps.required === nextProps.required &&
    prevProps.readOnly === nextProps.readOnly &&
    prevProps.helperText === nextProps.helperText &&
    prevProps.maxLength === nextProps.maxLength &&
    prevProps.showCharacterCount === nextProps.showCharacterCount &&
    prevProps.size === nextProps.size &&
    prevProps.className === nextProps.className &&
    prevProps.prefix === nextProps.prefix &&
    prevProps.icon === nextProps.icon &&
    prevProps.onChange === nextProps.onChange &&
    prevProps.id === nextProps.id &&
    prevProps.name === nextProps.name
  );
});

// Set display name for React DevTools
Input.displayName = "Input";

export default Input;
