import { useState, useRef, useCallback, ReactNode, TouchEvent } from 'react';
import { RefreshCw } from 'lucide-react';

interface PullToRefreshProps {
    onRefresh: () => Promise<void>;
    children: ReactNode;
    disabled?: boolean;
}

export function PullToRefresh({ onRefresh, children, disabled = false }: PullToRefreshProps) {
    const [pulling, setPulling] = useState(false);
    const [refreshing, setRefreshing] = useState(false);
    const [pullDistance, setPullDistance] = useState(0);

    const startY = useRef(0);
    const containerRef = useRef<HTMLDivElement>(null);

    const THRESHOLD = 80; // pixels to pull before triggering refresh
    const MAX_PULL = 120;

    const handleTouchStart = useCallback((e: TouchEvent) => {
        if (disabled || refreshing) return;

        const scrollTop = containerRef.current?.scrollTop || 0;
        if (scrollTop > 0) return; // Only trigger at top

        startY.current = e.touches[0].clientY;
        setPulling(true);
    }, [disabled, refreshing]);

    const handleTouchMove = useCallback((e: TouchEvent) => {
        if (!pulling || refreshing) return;

        const currentY = e.touches[0].clientY;
        const diff = currentY - startY.current;

        if (diff > 0) {
            // Add resistance to pull
            const resistance = Math.min(diff * 0.5, MAX_PULL);
            setPullDistance(resistance);
        }
    }, [pulling, refreshing]);

    const handleTouchEnd = useCallback(async () => {
        if (!pulling) return;

        setPulling(false);

        if (pullDistance >= THRESHOLD && !refreshing) {
            setRefreshing(true);
            setPullDistance(THRESHOLD);

            try {
                await onRefresh();
            } finally {
                setRefreshing(false);
                setPullDistance(0);
            }
        } else {
            setPullDistance(0);
        }
    }, [pulling, pullDistance, refreshing, onRefresh]);

    const progress = Math.min(pullDistance / THRESHOLD, 1);
    const rotation = progress * 180;

    return (
        <div
            ref={containerRef}
            onTouchStart={handleTouchStart}
            onTouchMove={handleTouchMove}
            onTouchEnd={handleTouchEnd}
            className="relative overflow-auto h-full"
        >
            {/* Pull indicator */}
            <div
                className="absolute left-1/2 -translate-x-1/2 z-10 flex items-center justify-center transition-transform"
                style={{
                    top: `${Math.max(-40, pullDistance - 40)}px`,
                    transform: `translateX(-50%) rotate(${rotation}deg)`,
                    opacity: progress
                }}
            >
                <div className={`p-2 rounded-full bg-white dark:bg-slate-800 shadow-lg ${refreshing ? 'animate-spin' : ''}`}>
                    <RefreshCw size={20} className="text-[var(--color-primary)]" />
                </div>
            </div>

            {/* Content with pull transform */}
            <div
                style={{
                    transform: `translateY(${pullDistance}px)`,
                    transition: pulling ? 'none' : 'transform 0.2s ease-out'
                }}
            >
                {children}
            </div>
        </div>
    );
}
