import { useState, useCallback, useRef } from 'react'
import { cn } from '@/lib/utils'
import { RefreshCw } from 'lucide-react'

interface PullToRefreshProps {
  onRefresh: () => Promise<void>
  children: React.ReactNode
  className?: string
}

export function PullToRefresh({ onRefresh, children, className }: PullToRefreshProps) {
  const [pulling, setPulling] = useState(false)
  const [pullDistance, setPullDistance] = useState(0)
  const [refreshing, setRefreshing] = useState(false)
  const touchStartY = useRef(0)
  const containerRef = useRef<HTMLDivElement>(null)

  const maxPullDistance = 100
  const refreshThreshold = 80

  const onTouchStart = useCallback((e: React.TouchEvent) => {
    // Only allow pull-to-refresh when at top of scroll
    if (containerRef.current && containerRef.current.scrollTop === 0) {
      touchStartY.current = e.targetTouches[0].clientY
      setPulling(true)
    }
  }, [])

  const onTouchMove = useCallback((e: React.TouchEvent) => {
    if (!pulling) return
    
    const currentY = e.targetTouches[0].clientY
    const diff = currentY - touchStartY.current
    
    if (diff > 0) {
      // Resistance increases as user pulls further
      const resistance = 1 + (diff / maxPullDistance) * 0.5
      const newDistance = Math.min(diff / resistance, maxPullDistance)
      setPullDistance(newDistance)
    }
  }, [pulling])

  const onTouchEnd = useCallback(async () => {
    if (!pulling) return
    
    if (pullDistance >= refreshThreshold && !refreshing) {
      setRefreshing(true)
      try {
        await onRefresh()
      } finally {
        setRefreshing(false)
      }
    }
    
    setPulling(false)
    setPullDistance(0)
  }, [pulling, pullDistance, refreshing, onRefresh])

  return (
    <div
      ref={containerRef}
      className={cn('relative overflow-y-auto', className)}
      onTouchStart={onTouchStart}
      onTouchMove={onTouchMove}
      onTouchEnd={onTouchEnd}
    >
      {/* Pull indicator */}
      <div
        className="absolute top-0 left-0 right-0 flex items-center justify-center transition-transform"
        style={{
          transform: `translateY(${pullDistance - 60}px)`,
          opacity: pulling ? 1 : 0,
        }}
      >
        <div className="flex flex-col items-center gap-2">
          <RefreshCw
            size={24}
            className={cn(
              'text-primary transition-transform',
              refreshing && 'animate-spin',
              !refreshing && pullDistance >= refreshThreshold && 'rotate-180'
            )}
          />
          <span className="text-xs text-text-secondary">
            {refreshing ? 'Refreshing...' : pullDistance >= refreshThreshold ? 'Release to refresh' : 'Pull to refresh'}
          </span>
        </div>
      </div>
      
      {/* Content with offset when pulling */}
      <div
        style={{
          transform: pulling ? `translateY(${pullDistance}px)` : 'translateY(0)',
          transition: pulling ? 'none' : 'transform 0.3s ease-out',
        }}
      >
        {children}
      </div>
    </div>
  )
}
