import React, { useRef } from 'react';
import { Animated, Modal, PanResponder, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useTheme } from '../../theme';
import { useKeyboardHeight } from '../../hooks/useKeyboardAvoiding';

interface BottomSheetProps {
  visible: boolean;
  onClose: () => void;
  title?: string;
  /** 内容可滚动（maxHeight 480），适合长表单。 */
  scrollable?: boolean;
  children: React.ReactNode;
}

/** 下滑关闭阈值（px）：超过此距离松手即关闭。 */
const DISMISS_THRESHOLD = 120;

/**
 * 通用底部弹窗容器：顶部 xl 圆角 + 把手、遮罩点击关闭、Android 返回键关闭、手势下滑关闭。
 *
 * 外层 BottomSheet 负责 Modal + SafeAreaProvider 包裹。
 * 关键：RN <Modal> 会脱离主窗口的 SafeAreaProvider context，导致内部
 * useSafeAreaInsets() 返回全 0，底部留白与键盘避让均失效。
 * 故在 Modal 内重新包一层 SafeAreaProvider 恢复 context。
 */
export function BottomSheet({ visible, onClose, title, scrollable, children }: BottomSheetProps) {
  return (
    <Modal visible={visible} transparent animationType="slide" onRequestClose={onClose}>
      <SafeAreaProvider>
        <BottomSheetContent onClose={onClose} title={title} scrollable={scrollable}>
          {children}
        </BottomSheetContent>
      </SafeAreaProvider>
    </Modal>
  );
}

function BottomSheetContent({ onClose, title, scrollable, children }: Omit<BottomSheetProps, 'visible'>) {
  const { theme } = useTheme();
  const insets = useSafeAreaInsets();
  const bottomInset = insets.bottom;
  // 手势下滑关闭的位移（仅手势，键盘避让改用响应式 paddingBottom）
  const translateY = useRef(new Animated.Value(0)).current;
  // 键盘高度：做响应式 paddingBottom（参考 BeeCount 方案，无残留）
  const kbHeight = useKeyboardHeight();
  const sheetHeight = useRef(0);

  // 手势下滑关闭
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => false,
      onMoveShouldSetPanResponder: (_evt, gestureState) => {
        // 仅在下滑且位移明显时拦截（避免与内部 ScrollView 冲突）
        return gestureState.dy > 10 && Math.abs(gestureState.dy) > Math.abs(gestureState.dx);
      },
      onPanResponderMove: (_evt, gestureState) => {
        if (gestureState.dy > 0) {
          translateY.setValue(gestureState.dy);
        }
      },
      onPanResponderRelease: (_evt, gestureState) => {
        if (gestureState.dy > DISMISS_THRESHOLD || gestureState.vy > 0.8) {
          // 下滑超过阈值或速度足够快 → 关闭
          Animated.timing(translateY, {
            toValue: sheetHeight.current || 600,
            duration: 200,
            useNativeDriver: true,
          }).start(() => {
            translateY.setValue(0);
            onClose();
          });
        } else {
          // 回弹
          Animated.spring(translateY, {
            toValue: 0,
            useNativeDriver: true,
            tension: 150,
            friction: 8,
          }).start();
        }
      },
    }),
  ).current;

  return (
    <Pressable style={[styles.overlay, { backgroundColor: theme.colors.overlay }]} onPress={onClose}>
      <Animated.View
        style={{ transform: [{ translateY }], width: '100%' }}
        onLayout={(e) => { sheetHeight.current = e.nativeEvent.layout.height; }}
      >
        <Pressable
          style={[styles.sheet, {
            backgroundColor: theme.colors.bgSecondary,
            borderTopLeftRadius: theme.radii.xl,
            borderTopRightRadius: theme.radii.xl,
            // 响应式 paddingBottom：基础留白(取安全区与24较大值) + 键盘高度
            paddingBottom: Math.max(bottomInset, 24) + kbHeight,
          }]}
          onPress={(e) => e.stopPropagation()}
        >
            {/* 把手区域：手势拖拽热区 */}
            <View {...panResponder.panHandlers} style={styles.handleArea}>
              <View style={[styles.handle, { backgroundColor: theme.colors.border }]} />
            </View>
            {title ? (
              <Text style={[theme.typography.h3, styles.title, { color: theme.colors.fgPrimary }]}>{title}</Text>
            ) : null}
            {scrollable ? (
              <ScrollView style={styles.scroll} keyboardShouldPersistTaps="handled" keyboardDismissMode="interactive">
                {children}
              </ScrollView>
            ) : (
              children
            )}
          </Pressable>
        </Animated.View>
      </Pressable>
  );
}

const styles = StyleSheet.create({
  overlay: { flex: 1, justifyContent: 'flex-end' },
  // paddingBottom 由内联动态计算（36 + 底部安全区），见上方 Pressable style
  sheet: { maxHeight: '85%', paddingHorizontal: 20 },
  handleArea: { alignItems: 'center', paddingTop: 8, paddingBottom: 4 },
  handle: { width: 40, height: 4, borderRadius: 2 },
  title: { marginTop: 8, marginBottom: 12 },
  scroll: { maxHeight: 480 },
});
