"use client"

import React, { useState, useRef, useEffect } from "react"
import { motion, useMotionValue, useTransform, animate, PanInfo } from "framer-motion"
import { cn } from "../../lib/utils"

export interface GestureDrawerProps {
  children: React.ReactNode
  isOpen: boolean
  onOpenChange: (open: boolean) => void
  direction?: "up" | "down" | "left" | "right"
  threshold?: number
  className?: string
  overlayClassName?: string
  enableSwipeToClose?: boolean
}

export const GestureDrawer = React.forwardRef<HTMLDivElement, GestureDrawerProps>(
  ({
    children,
    isOpen,
    onOpenChange,
    direction = "up",
    threshold = 50,
    className,
    overlayClassName,
    enableSwipeToClose = true,
    ...props
  }, ref) => {
    const y = useMotionValue(0)
    const x = useMotionValue(0)
    
    const isVertical = direction === "up" || direction === "down"
    const motionValue = isVertical ? y : x
    
    const opacity = useTransform(motionValue, [0, threshold], [1, 0.5])
    
    const handleDragEnd = (event: any, info: PanInfo) => {
      if (!enableSwipeToClose) return
      
      const offset = isVertical ? info.offset.y : info.offset.x
      const velocity = isVertical ? info.velocity.y : info.velocity.x
      
      let shouldClose = false
      
      switch (direction) {
        case "up":
          shouldClose = offset > threshold || velocity > 500
          break
        case "down":
          shouldClose = offset < -threshold || velocity < -500
          break
        case "left":
          shouldClose = offset > threshold || velocity > 500
          break
        case "right":
          shouldClose = offset < -threshold || velocity < -500
          break
      }
      
      if (shouldClose) {
        onOpenChange(false)
      } else {
        animate(motionValue, 0, { type: "spring", stiffness: 300, damping: 20 })
      }
    }
    
    const getInitialPosition = () => {
      switch (direction) {
        case "up":
          return { y: "100%" }
        case "down":
          return { y: "-100%" }
        case "left":
          return { x: "100%" }
        case "right":
          return { x: "-100%" }
        default:
          return { y: "100%" }
      }
    }
    
    const getAnimatePosition = () => {
      return isVertical ? { y: 0 } : { x: 0 }
    }
    
    if (!isOpen) return null
    
    return (
      <div className="fixed inset-0 z-50">
        {/* Overlay */}
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          onClick={() => onOpenChange(false)}
          className={cn("absolute inset-0 bg-black/50", overlayClassName)}
        />
        
        {/* Drawer */}
        <motion.div
          ref={ref}
          drag={enableSwipeToClose ? (isVertical ? "y" : "x") : false}
          dragConstraints={{ 
            top: direction === "up" ? 0 : undefined,
            bottom: direction === "down" ? 0 : undefined,
            left: direction === "left" ? 0 : undefined,
            right: direction === "right" ? 0 : undefined
          }}
          dragElastic={0.2}
          onDragEnd={handleDragEnd}
          style={{ 
            [isVertical ? "y" : "x"]: motionValue,
            opacity
          }}
          initial={getInitialPosition()}
          animate={getAnimatePosition()}
          exit={getInitialPosition()}
          transition={{ type: "spring", damping: 30, stiffness: 300 }}
          className={cn(
            "absolute bg-background border shadow-lg",
            {
              "bottom-0 left-0 right-0 rounded-t-lg": direction === "up",
              "top-0 left-0 right-0 rounded-b-lg": direction === "down", 
              "top-0 bottom-0 right-0 rounded-l-lg": direction === "left",
              "top-0 bottom-0 left-0 rounded-r-lg": direction === "right"
            },
            className
          )}
          {...props}
        >
          {/* Drag Handle */}
          {(direction === "up" || direction === "down") && (
            <div className="flex justify-center p-2">
              <div className="w-12 h-1 bg-muted rounded-full" />
            </div>
          )}
          
          {children}
        </motion.div>
      </div>
    )
  }
)

GestureDrawer.displayName = "GestureDrawer"