"use client"

import * as React from "react"
import { motion, AnimatePresence } from "framer-motion"
import { AlertCircle, Check } from "lucide-react"
import { cn } from "@/lib/utils"
import { fieldVariants } from "@/lib/animations"

export interface AnimatedInputProps
  extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string
  error?: string
  success?: boolean
  helperText?: string
  icon?: React.ReactNode
  rightIcon?: React.ReactNode
}

const AnimatedInput = React.forwardRef<HTMLInputElement, AnimatedInputProps>(
  (
    {
      className,
      type,
      label,
      error,
      success,
      helperText,
      icon,
      rightIcon,
      placeholder,
      ...props
    },
    ref
  ) => {
    const [isFocused, setIsFocused] = React.useState(false)
    const [hasValue, setHasValue] = React.useState(false)
    const inputRef = React.useRef<HTMLInputElement>(null)

    React.useImperativeHandle(ref, () => inputRef.current!)

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

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

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      setHasValue(e.target.value.length > 0)
      props.onChange?.(e)
    }

    React.useEffect(() => {
      if (inputRef.current) {
        setHasValue(inputRef.current.value.length > 0)
      }
    }, [props.value, props.defaultValue])

    const shouldFloatLabel = isFocused || hasValue || placeholder

    return (
      <div className="relative">
        <motion.div
          className={cn(
            "relative flex items-center",
            error && "animate-shake"
          )}
          animate={error ? "error" : isFocused ? "focus" : "initial"}
          variants={fieldVariants}
        >
          {icon && (
            <div className="absolute left-3 z-10 text-muted-foreground">
              {icon}
            </div>
          )}
          
          <motion.input
            ref={inputRef}
            type={type}
            className={cn(
              "flex h-12 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 transition-all duration-200",
              icon && "pl-10",
              (rightIcon || success || error) && "pr-10",
              error && "border-destructive focus-visible:ring-destructive",
              success && "border-green-500 focus-visible:ring-green-500",
              label && "pt-6",
              className
            )}
            placeholder={shouldFloatLabel ? placeholder : ""}
            onFocus={handleFocus}
            onBlur={handleBlur}
            onChange={handleChange}
            {...(props as any)}
          />

          {label && (
            <motion.label
              className={cn(
                "absolute left-3 text-sm text-muted-foreground pointer-events-none transition-all duration-200 origin-left",
                icon && "left-10",
                shouldFloatLabel
                  ? "top-2 text-xs scale-90"
                  : "top-1/2 -translate-y-1/2",
                isFocused && "text-primary",
                error && "text-destructive",
                success && "text-green-600"
              )}
              animate={{
                y: shouldFloatLabel ? -8 : 0,
                scale: shouldFloatLabel ? 0.85 : 1,
                color: isFocused
                  ? error
                    ? "hsl(var(--destructive))"
                    : success
                    ? "hsl(142, 76%, 36%)"
                    : "hsl(var(--primary))"
                  : "hsl(var(--muted-foreground))",
              }}
              transition={{ type: "spring", stiffness: 300, damping: 30 }}
            >
              {label}
            </motion.label>
          )}

          {(rightIcon || success || error) && (
            <div className="absolute right-3 flex items-center">
              <AnimatePresence mode="wait">
                {error ? (
                  <motion.div
                    key="error"
                    initial={{ opacity: 0, scale: 0.8 }}
                    animate={{ opacity: 1, scale: 1 }}
                    exit={{ opacity: 0, scale: 0.8 }}
                    transition={{ type: "spring", stiffness: 300, damping: 20 }}
                  >
                    <AlertCircle className="h-4 w-4 text-destructive" />
                  </motion.div>
                ) : success ? (
                  <motion.div
                    key="success"
                    initial={{ opacity: 0, scale: 0.8 }}
                    animate={{ opacity: 1, scale: 1 }}
                    exit={{ opacity: 0, scale: 0.8 }}
                    transition={{ type: "spring", stiffness: 300, damping: 20 }}
                  >
                    <Check className="h-4 w-4 text-green-600" />
                  </motion.div>
                ) : (
                  rightIcon && (
                    <motion.div
                      key="icon"
                      initial={{ opacity: 0 }}
                      animate={{ opacity: 1 }}
                      exit={{ opacity: 0 }}
                    >
                      {rightIcon}
                    </motion.div>
                  )
                )}
              </AnimatePresence>
            </div>
          )}
        </motion.div>

        <AnimatePresence>
          {(error || helperText) && (
            <motion.div
              initial={{ opacity: 0, y: -10, height: 0 }}
              animate={{ opacity: 1, y: 0, height: "auto" }}
              exit={{ opacity: 0, y: -10, height: 0 }}
              transition={{ type: "spring", stiffness: 300, damping: 30 }}
              className="mt-1 text-sm"
            >
              {error ? (
                <span className="text-destructive flex items-center gap-1">
                  <AlertCircle className="h-3 w-3" />
                  {error}
                </span>
              ) : (
                <span className="text-muted-foreground">{helperText}</span>
              )}
            </motion.div>
          )}
        </AnimatePresence>
      </div>
    )
  }
)

AnimatedInput.displayName = "AnimatedInput"

export { AnimatedInput }
