import React, { useRef, useEffect, useCallback, useState } from "react";
import {
  View,
  Text,
  StyleSheet,
  Modal,
  Animated,
  PanResponder,
  TouchableWithoutFeedback,
  Dimensions,
  ScrollView,
  LayoutChangeEvent,
} from "react-native";

const { height: SCREEN_HEIGHT } = Dimensions.get("window");
const MAX_SHEET_HEIGHT = SCREEN_HEIGHT * 0.93;

interface BottomSheetProps {
  visible: boolean;
  onClose: () => void;
  maxHeight?: number;
  title?: string;
  subtitle?: string;
  showHandle?: boolean;
  showOverlay?: boolean;
  closeOnOverlayPress?: boolean;
  scrollable?: boolean;
  children: React.ReactNode;
}

export default function BottomSheet({
  visible,
  onClose,
  maxHeight = MAX_SHEET_HEIGHT,
  title,
  subtitle,
  showHandle = true,
  showOverlay = true,
  closeOnOverlayPress = true,
  scrollable = false,
  children,
}: BottomSheetProps) {
  const [contentHeight, setContentHeight] = useState(0);
  const translateY = useRef(new Animated.Value(SCREEN_HEIGHT)).current;
  const overlayOpacity = useRef(new Animated.Value(0)).current;
  const lastGestureY = useRef(0);
  const measured = useRef(false);

  const sheetHeight = Math.min(contentHeight, maxHeight);

  const openSheet = useCallback(() => {
    Animated.parallel([
      Animated.spring(translateY, {
        toValue: 0,
        damping: 20,
        stiffness: 200,
        mass: 0.8,
        useNativeDriver: true,
      }),
      Animated.timing(overlayOpacity, {
        toValue: 1,
        duration: 280,
        useNativeDriver: true,
      }),
    ]).start();
  }, [translateY, overlayOpacity]);

  const closeSheet = useCallback(() => {
    Animated.parallel([
      Animated.spring(translateY, {
        toValue: sheetHeight || SCREEN_HEIGHT,
        damping: 20,
        stiffness: 200,
        mass: 0.8,
        useNativeDriver: true,
      }),
      Animated.timing(overlayOpacity, {
        toValue: 0,
        duration: 220,
        useNativeDriver: true,
      }),
    ]).start(() => {
      measured.current = false;
      setContentHeight(0);
      onClose();
    });
  }, [translateY, overlayOpacity, sheetHeight, onClose]);

  useEffect(() => {
    if (visible) {
      translateY.setValue(SCREEN_HEIGHT);
      measured.current = false;
    }
  }, [visible]);

  // Animate open once content is measured
  useEffect(() => {
    if (visible && contentHeight > 0) {
      translateY.setValue(sheetHeight);
      openSheet();
    }
  }, [visible, contentHeight]);

  const handleContentLayout = useCallback((e: LayoutChangeEvent) => {
    if (measured.current) return;
    const { height } = e.nativeEvent.layout;
    if (height > 0) {
      measured.current = true;
      setContentHeight(height);
    }
  }, []);

  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: (_, gestureState) =>
        Math.abs(gestureState.dy) > 5,
      onPanResponderGrant: () => {
        lastGestureY.current = 0;
      },
      onPanResponderMove: (_, gestureState) => {
        const dy = gestureState.dy;
        if (dy > 0) {
          translateY.setValue(dy);
        } else {
          translateY.setValue(dy * 0.1);
        }
        lastGestureY.current = dy;
      },
      onPanResponderRelease: (_, gestureState) => {
        const { dy, vy } = gestureState;
        const shouldClose =
          dy > (sheetHeight || SCREEN_HEIGHT) * 0.35 || vy > 1.2;
        if (shouldClose) {
          closeSheet();
        } else {
          Animated.spring(translateY, {
            toValue: 0,
            damping: 18,
            stiffness: 180,
            useNativeDriver: true,
          }).start();
        }
      },
    }),
  ).current;

  if (!visible) return null;

  const needsScroll = scrollable || contentHeight > maxHeight;
  const ContentWrapper = needsScroll ? ScrollView : View;
  const contentWrapperProps = needsScroll
    ? {
        bounces: false,
        showsVerticalScrollIndicator: false,
        contentContainerStyle: styles.scrollContent,
        keyboardShouldPersistTaps: "handled" as const,
      }
    : { style: styles.content };

  return (
    <Modal
      transparent
      visible={visible}
      animationType="none"
      statusBarTranslucent
      onRequestClose={closeSheet}
    >
      {showOverlay && (
        <TouchableWithoutFeedback
          onPress={closeOnOverlayPress ? closeSheet : undefined}
        >
          <Animated.View
            style={[
              styles.overlay,
              {
                opacity: overlayOpacity.interpolate({
                  inputRange: [0, 1],
                  outputRange: [0, 0.55],
                }),
              },
            ]}
          />
        </TouchableWithoutFeedback>
      )}

      {contentHeight === 0 && (
        <View
          style={styles.measureContainer}
          onLayout={handleContentLayout}
          pointerEvents="none"
        >
          {showHandle && (
            <View style={styles.handleZone}>
              <View style={styles.handle} />
            </View>
          )}
          {(title || subtitle) && (
            <View style={styles.header}>
              {title && <Text style={styles.title}>{title}</Text>}
              {subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
            </View>
          )}
          <View style={styles.content}>{children}</View>
        </View>
      )}

      {contentHeight > 0 && (
        <Animated.View
          style={[
            styles.sheet,
            {
              height: sheetHeight,
              transform: [{ translateY }],
            },
          ]}
        >
          <View {...panResponder.panHandlers} style={styles.handleZone}>
            {showHandle && <View style={styles.handle} />}
          </View>

          {(title || subtitle) && (
            <View style={styles.header}>
              {title && <Text style={styles.title}>{title}</Text>}
              {subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
            </View>
          )}

          <ContentWrapper {...contentWrapperProps}>{children}</ContentWrapper>
        </Animated.View>
      )}
    </Modal>
  );
}

const styles = StyleSheet.create({
  overlay: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: "#0a0a12",
  },
  measureContainer: {
    position: "absolute",
    left: 0,
    right: 0,
    bottom: -SCREEN_HEIGHT * 2,
    opacity: 0,
  },
  sheet: {
    position: "absolute",
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: "#ffffff",
    borderTopLeftRadius: 24,
    borderTopRightRadius: 24,
    shadowColor: "#000",
    shadowOffset: { width: 0, height: -6 },
    shadowOpacity: 0.12,
    shadowRadius: 20,
    elevation: 24,
  },
  handleZone: {
    alignItems: "center",
    paddingTop: 12,
    paddingBottom: 8,
  },
  handle: {
    width: 40,
    height: 4,
    borderRadius: 2,
    backgroundColor: "#D1D5DB",
  },
  header: {
    paddingHorizontal: 24,
    paddingBottom: 16,
    borderBottomWidth: 1,
    borderBottomColor: "#F3F4F6",
  },
  title: {
    fontSize: 17,
    fontWeight: "700",
    color: "#111827",
    letterSpacing: -0.3,
  },
  subtitle: {
    fontSize: 13,
    color: "#6B7280",
    marginTop: 2,
    fontWeight: "400",
  },
  content: {
    paddingHorizontal: 24,
    paddingTop: 16,
  },
  scrollContent: {
    paddingHorizontal: 24,
    paddingTop: 16,
    paddingBottom: 32,
  },
});
