import React, { useEffect, useMemo, useState, useRef } from 'react';
import { Modal, Pressable, StyleSheet, Text, View, PanResponder, Animated as RNAnimated, Image, ImageSourcePropType, Platform, useWindowDimensions } from 'react-native';
import { useTranslation } from 'react-i18next';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Animated, {
  Easing,
  runOnJS,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';

const FIXED_TOP_GAP = 100; // 统一距离顶部的高度

type Props = {
  visible: boolean;
  title?: string;
  onClose: () => void;
  children: React.ReactNode;
  leftIcon?: ImageSourcePropType; // 新增：支持自定义左侧图标
  height?: number; // 新增：支持自定义高度
};

/**
 * 通用底部上拉弹窗（Sheet）
 * - 内容区背景色固定：#FAF3EC
 * - 高度固定：默认距离顶部固定间距，也支持传入指定高度
 */
export default function SheetModal({ visible, title, onClose, children, leftIcon, height: customHeight }: Props) {
  const { t } = useTranslation();
  const insets = useSafeAreaInsets();
  const { width: windowWidth, height: windowHeight } = useWindowDimensions();
  const isTablet = Platform.OS === 'ios' && Math.min(windowWidth, windowHeight) >= 768;
  const [mounted, setMounted] = useState(false);
  const progress = useSharedValue(0); // 0: 关闭, 1: 打开
  const dragY = useSharedValue(0); // 拖拽位移

  const sheetHeight = customHeight || (isTablet ? Math.min(windowHeight - 72, 760) : (windowHeight - FIXED_TOP_GAP));

  useEffect(() => {
    if (visible) {
      setMounted(true);
      dragY.value = 0;
      progress.value = withTiming(1, { duration: 260, easing: Easing.out(Easing.cubic) });
      return;
    }
    if (!mounted) return;
    progress.value = withTiming(
      0,
      { duration: 220, easing: Easing.in(Easing.cubic) },
      (finished) => {
        if (finished) runOnJS(setMounted)(false);
      }
    );
  }, [visible, mounted, progress, dragY]);

  // 使用 PanResponder 处理下滑手势
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => false, 
      onMoveShouldSetPanResponder: () => false, // 暂时屏蔽下拉关闭手势，解决滑动冲突
      onPanResponderMove: (_, gestureState) => {
        if (gestureState.dy > 0) {
          dragY.value = gestureState.dy;
        }
      },
      onPanResponderRelease: (_, gestureState) => {
        if (gestureState.dy > 80 || gestureState.vy > 0.5) {
          runOnJS(onClose)();
        } else {
          dragY.value = withTiming(0, { 
            duration: 300, 
            easing: Easing.out(Easing.back(1)) 
          });
        }
      },
      onPanResponderTerminate: () => {
        dragY.value = withTiming(0, { duration: 200 });
      },
    })
  ).current;

  const overlayStyle = useAnimatedStyle(() => {
    return { opacity: 0.4 * progress.value };
  });

  const sheetStyle = useAnimatedStyle(() => {
    const baseTranslateY = (1 - progress.value) * sheetHeight; // 基础位移
    return { 
      transform: [{ translateY: baseTranslateY + dragY.value }] 
    };
  });

  const containerPaddingBottom = useMemo(() => {
    if (customHeight) return Math.max(insets.bottom, 16);
    return Math.max(insets.bottom, isTablet ? 20 : 80);
  }, [customHeight, insets.bottom, isTablet]);

  // 注意：Modal 的 visible 必须为 true 才会渲染，因此用 mounted 保持退场动画
  return (
    <Modal transparent visible={mounted} animationType="none" onRequestClose={onClose}>
      <View style={styles.root}>
        <Pressable 
          style={StyleSheet.absoluteFill} 
          onPress={onClose}
        >
          <Animated.View style={[styles.overlay, overlayStyle]} />
        </Pressable>

        <Animated.View
          {...panResponder.panHandlers}
          style={[
            styles.sheet,
            isTablet ? styles.sheetTablet : null,
            sheetStyle,
            {
              height: sheetHeight,
              paddingBottom: containerPaddingBottom,
            },
          ]}
        >
          <View style={styles.handleContainer}>
            <View style={styles.handle} />
          </View>
          <View style={styles.header}>
            <Text style={styles.title} numberOfLines={1}>
              {title ?? ''}
            </Text>
            <Pressable
              accessibilityRole="button"
              accessibilityLabel={leftIcon ? t('common.back') : t('common.close')}
              onPress={onClose}
              hitSlop={10}
              style={styles.close}
            >
              {leftIcon ? (
                <Image source={leftIcon} style={styles.backIcon} />
              ) : (
                <Text style={styles.closeText}>×</Text>
              )}
            </Pressable>
          </View>

          <View style={styles.body}>{children}</View>
        </Animated.View>
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  root: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  overlay: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: '#000',
  },
  sheet: {
    backgroundColor: '#FAF3EC',
    borderTopLeftRadius: 24,
    borderTopRightRadius: 24,
    paddingTop: 8,
    paddingHorizontal: 16,
  },
  sheetTablet: {
    width: '100%',
    alignSelf: 'stretch',
    borderTopLeftRadius: 24,
    borderTopRightRadius: 24,
    borderBottomLeftRadius: 0,
    borderBottomRightRadius: 0,
  },
  handleContainer: {
    alignItems: 'center',
    paddingVertical: 8,
  },
  handle: {
    width: 40,
    height: 5,
    borderRadius: 2.5,
    backgroundColor: 'rgba(94,42,40,0.15)',
  },
  header: {
    height: 44,
    justifyContent: 'center',
    alignItems: 'center',
  },
  title: {
    color: '#5E2A28',
    fontSize: 16,
    fontWeight: '700',
  },
  close: {
    position: 'absolute',
    left: 4,
    top: 0,
    height: 44,
    width: 44,
    alignItems: 'center',
    justifyContent: 'center',
  },
  closeText: {
    color: '#5E2A28',
    fontSize: 28,
    lineHeight: 28,
    fontWeight: '400',
  },
  backIcon: {
    width: 20,
    height: 20,
    resizeMode: 'contain',
  },
  body: {
    paddingTop: 10,
    flex: 1,
  },
});
