import React, { ReactNode, useRef, useCallback, useMemo } from 'react';
import { Animated, GestureResponderEvent, PanResponder, PanResponderGestureState, View } from 'react-native';
import { getDistance, getScale } from './_helpers';

const PanContainer = ({
	children,
	close,
	setIsDragging
}: {
	children: ReactNode;
	close: () => void;
	setIsDragging: (isDragging: boolean) => void;
}) => {
	const translationXY = useRef(new Animated.ValueXY()).current;
	const scale = useRef(new Animated.Value(1)).current;
	let _initialTouches = useRef<any>([]).current;

	const onRelease = useCallback(
		(_: GestureResponderEvent, gestureState: PanResponderGestureState): void | boolean => {
			setIsDragging(false);

			if (gestureState.dy > 180 && _initialTouches.length === 1) {
				close();
				return false;
			}

			// Reset with animation
			Animated.parallel([
				Animated.timing(scale, {
					duration: 100,
					toValue: 1,
					useNativeDriver: true
				}),
				Animated.timing(translationXY.x, {
					duration: 100,
					toValue: 0,
					useNativeDriver: true
				}),
				Animated.timing(translationXY.y, {
					duration: 100,
					toValue: 0,
					useNativeDriver: true
				})
			]).start();
		},
		[close, scale, translationXY.x, translationXY.y, setIsDragging, _initialTouches.length]
	);

	// Create panResponder with memoization
	const panResponder = useMemo(
		() =>
			PanResponder.create({
				onStartShouldSetPanResponder: () => true,
				onMoveShouldSetPanResponder: (_: GestureResponderEvent, gestureState: PanResponderGestureState) => {
					const { dx, dy, numberActiveTouches } = gestureState;
					const absDx = Math.abs(dx);
					const absDY = Math.abs(dy);

					// Improved gesture recognition logic
					if (absDY > 5 && absDx <= 2 && numberActiveTouches <= 1) {
						return true;
					}
					if (absDx > 0 && numberActiveTouches <= 1) {
						return false;
					}
					return true;
				},
				onPanResponderGrant: (evt: GestureResponderEvent) => {
					setIsDragging(true);
					_initialTouches = evt.nativeEvent.touches;
					translationXY.setOffset({ x: 0, y: 0 });
					return true;
				},
				onPanResponderMove: (evt: GestureResponderEvent, gestureState: PanResponderGestureState) => {
					const { touches } = evt.nativeEvent;
					const { dx, dy } = gestureState;

					if (touches.length <= 1) {
						// Handle vertical swipe to close
						if (Math.abs(dy) > 10) {
							translationXY.y.setValue(dy);
							return true;
						}

						// Handle horizontal swipe
						if (Math.abs(dx) > 0) {
							setIsDragging(false);
							return false;
						}

						// Not enough touches for pinch-zoom
						if (touches.length < 2) {
							onRelease(evt, gestureState);
							return false;
						}
					}

					// Handle pinch zoom and pan
					translationXY.x.setValue(dx);
					translationXY.y.setValue(dy);

					// Calculate scale for zooming
					const currentDistance = getDistance(touches);
					const initialDistance = getDistance(_initialTouches);
					if (currentDistance && initialDistance) {
						const newScale = getScale(currentDistance, initialDistance);
						scale.setValue(newScale);
					}

					return true;
				},
				onPanResponderRelease: onRelease,
				onPanResponderTerminate: () => true,
				onPanResponderTerminationRequest: () => true
			}),
		[onRelease, setIsDragging, translationXY, scale]
	);

	return (
		<View style={{ flex: 1 }}>
			<Animated.View
				{...panResponder.panHandlers}
				style={{
					flex: 1,
					transform: [{ translateX: translationXY.x }, { translateY: translationXY.y }, { scale }]
				}}>
				{children}
			</Animated.View>
		</View>
	);
};

export default React.memo(PanContainer);
