'use client';

import { motion, AnimatePresence } from 'framer-motion';
import { ReactNode, useState, useRef, useEffect, forwardRef } from 'react';
import { EyeIcon, EyeSlashIcon, ExclamationCircleIcon, CheckCircleIcon } from '@heroicons/react/24/outline';

interface EnhancedInputProps {
  type?: 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search';
  placeholder?: string;
  value?: string;
  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
  onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
  onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
  label?: string;
  error?: string;
  success?: string;
  hint?: string;
  disabled?: boolean;
  required?: boolean;
  leftIcon?: ReactNode;
  rightIcon?: ReactNode;
  className?: string;
  containerClassName?: string;
  autoFocus?: boolean;
  autoComplete?: string;
  name?: string;
  id?: string;
  showPasswordToggle?: boolean;
  showStrengthIndicator?: boolean;
  showCharCount?: boolean;
  maxLength?: number;
  minLength?: number;
  pattern?: string;
  validate?: (value: string) => string | null;
  onValidationChange?: (isValid: boolean) => void;
}

const EnhancedInput = forwardRef<HTMLInputElement, EnhancedInputProps>(({
  type = 'text',
  placeholder,
  value = '',
  onChange,
  onFocus,
  onBlur,
  label,
  error,
  success,
  hint,
  disabled = false,
  required = false,
  leftIcon,
  rightIcon,
  className = '',
  containerClassName = '',
  autoFocus = false,
  autoComplete,
  name,
  id,
  showPasswordToggle = false,
  showStrengthIndicator = false,
  showCharCount = false,
  maxLength,
  minLength,
  pattern,
  validate,
  onValidationChange,
  ...props
}, ref) => {
  const [isFocused, setIsFocused] = useState(false);
  const [isPasswordVisible, setIsPasswordVisible] = useState(false);
  const [internalValue, setInternalValue] = useState(value);
  const [validationMessage, setValidationMessage] = useState<string | null>(null);
  const [isValidating, setIsValidating] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  // 同步外部值
  useEffect(() => {
    setInternalValue(value);
  }, [value]);

  // 验证逻辑
  useEffect(() => {
    if (validate && internalValue) {
      setIsValidating(true);
      const message = validate(internalValue);
      setValidationMessage(message);
      setIsValidating(false);
      
      if (onValidationChange) {
        onValidationChange(!message);
      }
    }
  }, [internalValue, validate, onValidationChange]);

  // 密码强度计算
  const getPasswordStrength = (password: string) => {
    let strength = 0;
    if (password.length >= 8) strength++;
    if (/[a-z]/.test(password)) strength++;
    if (/[A-Z]/.test(password)) strength++;
    if (/[0-9]/.test(password)) strength++;
    if (/[^A-Za-z0-9]/.test(password)) strength++;
    return strength;
  };

  const passwordStrength = type === 'password' && showStrengthIndicator ? getPasswordStrength(internalValue) : 0;

  const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {
    setIsFocused(true);
    onFocus?.(e);
  };

  const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
    setIsFocused(false);
    onBlur?.(e);
  };

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

  const togglePasswordVisibility = () => {
    setIsPasswordVisible(!isPasswordVisible);
  };

  const getInputType = () => {
    if (type === 'password' && showPasswordToggle) {
      return isPasswordVisible ? 'text' : 'password';
    }
    return type;
  };

  const getBorderColor = () => {
    if (error || validationMessage) return 'border-red-500 focus:border-red-500 focus:ring-red-500';
    if (success || (validationMessage === null && internalValue && validate)) return 'border-green-500 focus:border-green-500 focus:ring-green-500';
    if (isFocused) return 'border-orange-500 focus:border-orange-500 focus:ring-orange-500';
    return 'border-gray-300 dark:border-gray-600 focus:border-orange-500 focus:ring-orange-500';
  };

  const getLabelColor = () => {
    if (error || validationMessage) return 'text-red-600 dark:text-red-400';
    if (success || (validationMessage === null && internalValue && validate)) return 'text-green-600 dark:text-green-400';
    if (isFocused) return 'text-orange-600 dark:text-orange-400';
    return 'text-gray-700 dark:text-gray-300';
  };

  const inputVariants = {
    initial: { scale: 1 },
    focus: { 
      scale: 1.02,
      transition: { duration: 0.2, ease: "easeOut" }
    },
    blur: {
      scale: 1,
      transition: { duration: 0.2, ease: "easeOut" }
    }
  };

  const labelVariants = {
    initial: { y: 0, scale: 1 },
    focus: { 
      y: -20, 
      scale: 0.85,
      transition: { duration: 0.2, ease: "easeOut" }
    },
    blur: {
      y: internalValue ? -20 : 0,
      scale: internalValue ? 0.85 : 1,
      transition: { duration: 0.2, ease: "easeOut" }
    }
  };

  return (
    <motion.div
      ref={containerRef}
      className={`relative ${containerClassName}`}
      initial="initial"
      animate={isFocused ? "focus" : "blur"}
      variants={inputVariants}
    >
      {/* 标签 */}
      {label && (
        <motion.label
          htmlFor={id}
          className={`absolute left-3 z-10 bg-white dark:bg-gray-800 px-1 text-sm font-medium transition-all duration-200 ${
            isFocused || internalValue ? 'text-xs' : 'text-base'
          } ${getLabelColor()}`}
          initial="initial"
          animate={isFocused ? "focus" : "blur"}
          variants={labelVariants}
        >
          {label}
          {required && <span className="text-red-500 ml-1">*</span>}
        </motion.label>
      )}

      {/* 输入框容器 */}
      <motion.div
        className={`relative flex items-center bg-white dark:bg-gray-800 border-2 rounded-lg transition-all duration-200 ${
          getBorderColor()
        } ${disabled ? 'bg-gray-100 dark:bg-gray-700 cursor-not-allowed' : ''}`}
        whileHover={!disabled ? { scale: 1.01 } : {}}
        animate={{
          boxShadow: isFocused ? '0 0 0 3px rgba(249, 115, 22, 0.1)' : '0 1px 3px 0 rgba(0, 0, 0, 0.1)'
        }}
        transition={{ duration: 0.2 }}
      >
        {/* 左侧图标 */}
        {leftIcon && (
          <motion.div
            className="absolute left-3 text-gray-400 dark:text-gray-500"
            initial={{ opacity: 0, x: -10 }}
            animate={{ opacity: 1, x: 0 }}
            transition={{ delay: 0.1 }}
          >
            {leftIcon}
          </motion.div>
        )}

        {/* 输入框 */}
        <input
          ref={ref || inputRef}
          type={getInputType()}
          placeholder={!label ? placeholder : ''}
          value={internalValue}
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          disabled={disabled}
          required={required}
          autoFocus={autoFocus}
          autoComplete={autoComplete}
          name={name}
          id={id}
          maxLength={maxLength}
          minLength={minLength}
          pattern={pattern}
          className={`w-full bg-transparent border-0 outline-none focus:ring-0 transition-all duration-200 ${
            leftIcon ? 'pl-10' : 'pl-4'
          } ${
            rightIcon || (type === 'password' && showPasswordToggle) ? 'pr-10' : 'pr-4'
          } ${
            size === 'sm' ? 'py-2 text-sm' : size === 'lg' ? 'py-3 text-lg' : 'py-2.5 text-base'
          } ${className}`}
          {...props}
        />

        {/* 验证状态图标 */}
        <AnimatePresence>
          {isValidating && (
            <motion.div
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.8 }}
              className="absolute right-3 text-orange-500"
            >
              <motion.div
                animate={{ rotate: 360 }}
                transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
                className="w-4 h-4 border-2 border-orange-500 border-t-transparent rounded-full"
              />
            </motion.div>
          )}
          
          {!isValidating && validationMessage === null && internalValue && validate && (
            <motion.div
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.8 }}
              className="absolute right-3 text-green-500"
            >
              <CheckCircleIcon className="w-5 h-5" />
            </motion.div>
          )}
          
          {(error || validationMessage) && (
            <motion.div
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.8 }}
              className="absolute right-3 text-red-500"
            >
              <ExclamationCircleIcon className="w-5 h-5" />
            </motion.div>
          )}
        </AnimatePresence>

        {/* 右侧图标和密码切换 */}
        <div className="absolute right-3 flex items-center space-x-2">
          {type === 'password' && showPasswordToggle && (
            <motion.button
              type="button"
              onClick={togglePasswordVisibility}
              className="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 transition-colors duration-200"
              whileHover={{ scale: 1.1 }}
              whileTap={{ scale: 0.9 }}
            >
              {isPasswordVisible ? <EyeSlashIcon className="w-5 h-5" /> : <EyeIcon className="w-5 h-5" />}
            </motion.button>
          )}
          
          {rightIcon && (
            <motion.div
              initial={{ opacity: 0, x: 10 }}
              animate={{ opacity: 1, x: 0 }}
              transition={{ delay: 0.1 }}
            >
              {rightIcon}
            </motion.div>
          )}
        </div>
      </motion.div>

      {/* 密码强度指示器 */}
      {type === 'password' && showStrengthIndicator && internalValue && (
        <motion.div
          initial={{ opacity: 0, height: 0 }}
          animate={{ opacity: 1, height: 'auto' }}
          exit={{ opacity: 0, height: 0 }}
          className="mt-2"
        >
          <div className="flex space-x-1">
            {[1, 2, 3, 4, 5].map((level) => (
              <motion.div
                key={level}
                className={`h-1 flex-1 rounded-full transition-all duration-300 ${
                  passwordStrength >= level
                    ? level <= 2
                      ? 'bg-red-500'
                      : level <= 3
                      ? 'bg-yellow-500'
                      : 'bg-green-500'
                    : 'bg-gray-200 dark:bg-gray-700'
                }`}
                initial={{ scaleX: 0 }}
                animate={{ scaleX: passwordStrength >= level ? 1 : 0.3 }}
                transition={{ delay: level * 0.1 }}
              />
            ))}
          </div>
          <motion.p
            className="text-xs mt-1 text-gray-600 dark:text-gray-400"
            initial={{ opacity: 0, y: -5 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: 0.2 }}
          >
            {passwordStrength <= 2 && '密码强度：弱'}
            {passwordStrength === 3 && '密码强度：中等'}
            {passwordStrength >= 4 && '密码强度：强'}
          </motion.p>
        </motion.div>
      )}

      {/* 字符计数 */}
      {showCharCount && maxLength && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          className="flex justify-between items-center mt-1"
        >
          <div />
          <motion.span
            className={`text-xs ${
              internalValue.length > maxLength
                ? 'text-red-500'
                : internalValue.length > maxLength * 0.8
                ? 'text-yellow-500'
                : 'text-gray-500'
            }`}
            animate={{
              scale: internalValue.length > maxLength ? 1.1 : 1,
              color: internalValue.length > maxLength ? '#ef4444' : internalValue.length > maxLength * 0.8 ? '#f59e0b' : '#6b7280'
            }}
          >
            {internalValue.length}/{maxLength}
          </motion.span>
        </motion.div>
      )}

      {/* 错误信息 */}
      <AnimatePresence>
        {(error || validationMessage) && (
          <motion.div
            initial={{ opacity: 0, height: 0, y: -10 }}
            animate={{ opacity: 1, height: 'auto', y: 0 }}
            exit={{ opacity: 0, height: 0, y: -10 }}
            className="mt-1 text-sm text-red-600 dark:text-red-400 flex items-center space-x-1"
          >
            <ExclamationCircleIcon className="w-4 h-4 flex-shrink-0" />
            <span>{error || validationMessage}</span>
          </motion.div>
        )}
      </AnimatePresence>

      {/* 成功信息 */}
      <AnimatePresence>
        {success && (
          <motion.div
            initial={{ opacity: 0, height: 0, y: -10 }}
            animate={{ opacity: 1, height: 'auto', y: 0 }}
            exit={{ opacity: 0, height: 0, y: -10 }}
            className="mt-1 text-sm text-green-600 dark:text-green-400 flex items-center space-x-1"
          >
            <CheckCircleIcon className="w-4 h-4 flex-shrink-0" />
            <span>{success}</span>
          </motion.div>
        )}
      </AnimatePresence>

      {/* 提示信息 */}
      <AnimatePresence>
        {hint && !error && !validationMessage && !success && (
          <motion.div
            initial={{ opacity: 0, height: 0, y: -10 }}
            animate={{ opacity: 1, height: 'auto', y: 0 }}
            exit={{ opacity: 0, height: 0, y: -10 }}
            className="mt-1 text-sm text-gray-600 dark:text-gray-400"
          >
            {hint}
          </motion.div>
        )}
      </AnimatePresence>
    </motion.div>
  );
});

EnhancedInput.displayName = 'EnhancedInput';

export default EnhancedInput;
