"use client"

import React, { useRef, useState, useEffect } from "react"
import { motion, AnimatePresence } from "framer-motion"
import { Loader2, Check, X, Sparkles } from "lucide-react"
import { cn } from "../../lib/utils"
import { cva, type VariantProps } from "class-variance-authority"

const enhancedButtonVariants = cva(
  "relative inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 overflow-hidden transform active:scale-[0.98] rounded-lg",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground dark:bg-primary dark:text-primary-foreground hover:bg-primary/90 dark:hover:bg-primary/90 shadow-sm hover:shadow-md",
        destructive: "bg-destructive text-destructive-foreground dark:bg-destructive dark:text-destructive-foreground hover:bg-destructive/90 dark:hover:bg-destructive/90 shadow-sm hover:shadow-md",
        outline: "border border-input dark:border-input bg-background dark:bg-background text-foreground dark:text-foreground hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground transition-all duration-200",
        secondary: "bg-muted text-muted-foreground dark:bg-muted dark:text-muted-foreground hover:bg-muted/80 dark:hover:bg-muted/80 border border-input dark:border-input shadow-sm hover:shadow-md",
        ghost: "text-foreground dark:text-foreground hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground transition-all duration-200",
        link: "text-primary underline-offset-4 hover:underline hover:text-primary/80",
        gradient: "bg-gradient-to-r from-purple-600 to-pink-600 text-white hover:from-purple-700 hover:to-pink-700 shadow-md hover:shadow-lg",
        glow: "bg-primary text-primary-foreground shadow-lg shadow-primary/50 hover:shadow-xl hover:shadow-primary/60",
      },
      size: {
        default: "h-10 px-4 py-2",
        sm: "h-9 px-3",
        lg: "h-11 px-8",
        icon: "h-10 w-10",
      },
      animation: {
        ripple: "ripple-effect",
        morph: "morph-effect",
        particles: "particles-effect",
        magnetic: "magnetic-effect",
        glitch: "glitch-effect",
      }
    },
    defaultVariants: {
      variant: "default",
      size: "default",
      animation: "ripple",
    },
  }
)

interface RippleEffect {
  x: number
  y: number
  id: number
}

export interface ButtonProProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof enhancedButtonVariants> {
  state?: "idle" | "loading" | "success" | "error"
  onStateChange?: (state: "idle" | "loading" | "success" | "error") => void
  enableRipple?: boolean
  enableMorph?: boolean
  enableParticles?: boolean
  enableMagnetic?: boolean
  enableGlitch?: boolean
}

export const ButtonPro = React.forwardRef<HTMLButtonElement, ButtonProProps>(
  ({ 
    className, 
    variant, 
    size, 
    animation,
    state = "idle", 
    onStateChange, 
    children, 
    onClick,
    enableRipple = true,
    enableMorph = true,
    enableParticles = false,
    enableMagnetic = false,
    enableGlitch = false,
    disabled,
    type = "button",
    ...props 
  }, ref) => {
    const [internalState, setInternalState] = useState<"idle" | "loading" | "success" | "error">("idle")
    const [ripples, setRipples] = useState<RippleEffect[]>([])
    const [particles, setParticles] = useState<{ x: number; y: number; id: number }[]>([])
    const [magneticPosition, setMagneticPosition] = useState({ x: 0, y: 0 })
    const buttonRef = useRef<HTMLButtonElement>(null)
    const currentState = state !== "idle" ? state : internalState

    // Ripple effect
    const createRipple = (event: React.MouseEvent<HTMLButtonElement>) => {
      if (!enableRipple) return
      
      const button = event.currentTarget
      const rect = button.getBoundingClientRect()
      const ripple = {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top,
        id: Date.now()
      }
      
      setRipples([...ripples, ripple])
      setTimeout(() => {
        setRipples(prev => prev.filter(r => r.id !== ripple.id))
      }, 1000)
    }

    // Particle effect
    const createParticles = (event: React.MouseEvent<HTMLButtonElement>) => {
      if (!enableParticles) return
      
      const button = event.currentTarget
      const rect = button.getBoundingClientRect()
      const newParticles = Array.from({ length: 8 }, (_, i) => ({
        x: event.clientX - rect.left,
        y: event.clientY - rect.top,
        id: Date.now() + i
      }))
      
      setParticles([...particles, ...newParticles])
      setTimeout(() => {
        setParticles([])
      }, 1000)
    }

    // Magnetic effect
    const handleMouseMove = (event: React.MouseEvent<HTMLButtonElement>) => {
      if (!enableMagnetic) return
      
      const button = event.currentTarget
      const rect = button.getBoundingClientRect()
      const centerX = rect.width / 2
      const centerY = rect.height / 2
      const x = event.clientX - rect.left - centerX
      const y = event.clientY - rect.top - centerY
      
      setMagneticPosition({
        x: x * 0.2,
        y: y * 0.2
      })
    }

    const handleMouseLeave = () => {
      if (enableMagnetic) {
        setMagneticPosition({ x: 0, y: 0 })
      }
    }

    const handleClick = async (e: React.MouseEvent<HTMLButtonElement>) => {
      createRipple(e)
      createParticles(e)
      
      if (currentState === "loading") return

      if (enableMorph) {
        setInternalState("loading")
        onStateChange?.("loading")
      }

      if (onClick) {
        try {
          await onClick(e)
          if (enableMorph) {
            setInternalState("success")
            onStateChange?.("success")
            
            setTimeout(() => {
              setInternalState("idle")
              onStateChange?.("idle")
            }, 2000)
          }
        } catch (error) {
          if (enableMorph) {
            setInternalState("error")
            onStateChange?.("error")
            
            setTimeout(() => {
              setInternalState("idle")
              onStateChange?.("idle")
            }, 2000)
          }
        }
      }
    }

    const getIcon = () => {
      switch (currentState) {
        case "loading":
          return <Loader2 className="h-4 w-4 animate-spin" />
        case "success":
          return <Check className="h-4 w-4" />
        case "error":
          return <X className="h-4 w-4" />
        default:
          return null
      }
    }

    const getBackgroundColor = () => {
      switch (currentState) {
        case "success":
          return "bg-success"
        case "error":
          return "bg-destructive"
        default:
          return ""
      }
    }

    return (
      <motion.button
        className={cn(enhancedButtonVariants({ variant, size }), className)}
        ref={buttonRef || ref}
        onClick={handleClick}
        onMouseMove={handleMouseMove}
        onMouseLeave={handleMouseLeave}
        disabled={currentState === "loading" || disabled}
        type={type}
        animate={{
          x: magneticPosition.x,
          y: magneticPosition.y,
        }}
        transition={{
          type: "spring",
          stiffness: 150,
          damping: 15,
          mass: 0.1
        }}
      >
        {/* Ripple effects */}
        <AnimatePresence>
          {ripples.map((ripple) => (
            <motion.span
              key={ripple.id}
              className="absolute rounded-full bg-white/30 pointer-events-none"
              style={{
                left: ripple.x,
                top: ripple.y,
              }}
              initial={{ width: 0, height: 0, x: 0, y: 0, opacity: 1 }}
              animate={{ 
                width: 200, 
                height: 200, 
                x: -100, 
                y: -100, 
                opacity: 0 
              }}
              exit={{ opacity: 0 }}
              transition={{ duration: 1, ease: "easeOut" }}
            />
          ))}
        </AnimatePresence>

        {/* Particle effects */}
        <AnimatePresence>
          {particles.map((particle, i) => (
            <motion.span
              key={particle.id}
              className="absolute w-1 h-1 bg-primary rounded-full pointer-events-none"
              style={{
                left: particle.x,
                top: particle.y,
              }}
              initial={{ scale: 0, opacity: 1 }}
              animate={{ 
                scale: [0, 1, 0],
                x: (i % 2 === 0 ? 1 : -1) * (20 + Math.random() * 30),
                y: -20 - Math.random() * 30,
                opacity: [1, 1, 0]
              }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.6, ease: "easeOut" }}
            />
          ))}
        </AnimatePresence>

        {/* Morph content */}
        <motion.div
          className="flex items-center gap-2"
          animate={{
            width: currentState !== "idle" ? "auto" : "100%"
          }}
          transition={{ duration: 0.2 }}
        >
          <AnimatePresence mode="wait">
            {currentState !== "idle" && (
              <motion.div
                initial={{ scale: 0, opacity: 0 }}
                animate={{ scale: 1, opacity: 1 }}
                exit={{ scale: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="flex items-center"
              >
                {getIcon()}
              </motion.div>
            )}
          </AnimatePresence>
          
          <motion.span
            animate={{
              opacity: currentState === "idle" ? 1 : 0,
              x: currentState !== "idle" ? -20 : 0
            }}
            transition={{ duration: 0.2 }}
          >
            {children}
          </motion.span>
        </motion.div>

        {/* Background animation for success/error states */}
        <AnimatePresence>
          {(currentState === "success" || currentState === "error") && (
            <motion.div
              className={cn(
                "absolute inset-0 rounded-md -z-10",
                getBackgroundColor()
              )}
              initial={{ scale: 0, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              exit={{ scale: 0, opacity: 0 }}
              transition={{ duration: 0.3 }}
            />
          )}
        </AnimatePresence>

        {/* Glitch effect overlay */}
        {enableGlitch && (
          <motion.div
            className="absolute inset-0 pointer-events-none"
            animate={{
              opacity: [0, 0.1, 0, 0.2, 0],
              clipPath: [
                "inset(0 0 100% 0)",
                "inset(20% 0 60% 0)",
                "inset(40% 0 40% 0)",
                "inset(80% 0 10% 0)",
                "inset(0 0 100% 0)",
              ]
            }}
            transition={{
              duration: 0.5,
              repeat: Infinity,
              repeatDelay: 5,
            }}
            style={{
              background: "linear-gradient(45deg, #ff0080, #00ff88, #0080ff)",
              mixBlendMode: "screen"
            }}
          />
        )}

        {/* Sparkle decoration for special variants */}
        {variant === "gradient" && (
          <Sparkles className="absolute top-1 right-1 h-3 w-3 text-white/50 animate-pulse" />
        )}
      </motion.button>
    )
  }
)

ButtonPro.displayName = "ButtonPro"

export { ButtonPro as Button, enhancedButtonVariants }