import React, { useEffect, useImperativeHandle, forwardRef, ReactNode, useCallback, useMemo } from 'react'
import {
    View,
    StyleSheet,
    Pressable,
    useWindowDimensions,
    BackHandler,
    Modal,
    Platform,
} from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { CloseIcon } from '@/components/icon'
import Animated, {
    useSharedValue,
    useAnimatedStyle,
    withSpring,
    withTiming,
    runOnJS,
    interpolate,
    Extrapolation,
} from 'react-native-reanimated'
import { Gesture, GestureDetector } from 'react-native-gesture-handler'

const AnimatedPressable = Animated.createAnimatedComponent(Pressable)

export type DrawerPosition = 'bottom' | 'top' | 'left' | 'right'

export interface DrawerProps {
    /**
     * 是否显示抽屉
     */
    visible: boolean
    /**
     * 关闭回调
     */
    onClose: () => void
    /**
     * 抽屉内容
     */
    children: ReactNode
    /**
     * 抽屉位置，默认为 'bottom'
     */
    position?: DrawerPosition
    /**
     * 抽屉高度（position 为 'top' 或 'bottom' 时使用）
     */
    height?: number | string
    /**
     * 抽屉宽度（position 为 'left' 或 'right' 时使用）
     */
    width?: number | string
    /**
     * 是否显示遮罩层，默认为 true
     */
    showBackdrop?: boolean
    /**
     * 遮罩层颜色，默认为 'rgba(0, 0, 0, 0.5)'
     */
    backdropColor?: string
    /**
     * 点击遮罩层是否关闭，默认为 true
     */
    closeOnBackdropPress?: boolean
    /**
     * 是否支持手势拖拽关闭，默认为 true
     */
    enableGesture?: boolean
    /**
     * 拖拽关闭的阈值（速度），默认为 500
     */
    swipeVelocityThreshold?: number
    /**
     * 自定义样式
     */
    style?: any
    /**
     * 遮罩层样式
     */
    backdropStyle?: any
    /**
     * 是否显示关闭按钮，默认为 true
     */
    showCloseButton?: boolean
}

export interface DrawerRef {
    /**
     * 关闭抽屉
     */
    close: () => void
}

const Drawer = forwardRef<DrawerRef, DrawerProps>(
    (
        {
            visible,
            onClose,
            children,
            position = 'bottom',
            height,
            width,
            showBackdrop = true,
            backdropColor = 'rgba(0, 0, 0, 0.5)',
            closeOnBackdropPress = true,
            enableGesture = true,
            swipeVelocityThreshold = 500,
            style,
            backdropStyle,
            showCloseButton = true,
        },
        ref,
    ) => {
        const { width: screenWidth, height: screenHeight } = useWindowDimensions()
        const insets = useSafeAreaInsets()
        const translateX = useSharedValue(0)
        const translateY = useSharedValue(0)
        const backdropOpacity = useSharedValue(0)

        // 计算抽屉尺寸
        const drawerHeight =
            height === undefined
                ? screenHeight * 0.6
                : typeof height === 'string'
                  ? (parseFloat(height) / 100) * screenHeight
                  : height
        const drawerWidth =
            width === undefined
                ? screenWidth * 0.8
                : typeof width === 'string'
                  ? (parseFloat(width) / 100) * screenWidth
                  : width

        // 根据位置计算最大偏移量
        const getMaxOffset = () => {
            switch (position) {
                case 'bottom':
                    return drawerHeight
                case 'top':
                    return -drawerHeight
                case 'left':
                    return -drawerWidth
                case 'right':
                    return drawerWidth
                default:
                    return drawerHeight
            }
        }

        const maxOffset = getMaxOffset()
        const isHorizontal = position === 'left' || position === 'right'

        // 关闭抽屉
        const close = useCallback(() => {
            translateX.value = 0
            translateY.value = 0
            backdropOpacity.value = withTiming(0, { duration: 200 })
            onClose()
        }, [onClose])

        useImperativeHandle(ref, () => ({
            close,
        }), [close])

        // 处理返回键（仅 Android）
        useEffect(() => {
            if (!visible || Platform.OS !== 'android') return

            const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
                close()
                return true
            })

            return () => backHandler.remove()
        }, [visible, close])

        // 显示/隐藏动画
        useEffect(() => {
            if (visible) {
                backdropOpacity.value = withTiming(1, { duration: 200 })
                translateX.value = 0
                translateY.value = 0
            } else {
                backdropOpacity.value = withTiming(0, { duration: 200 })
                translateX.value = 0
                translateY.value = 0
            }
        }, [visible])

        // 手势处理
        const pan = Gesture.Pan()
            .enabled(enableGesture && visible)
            .onUpdate((event) => {
                if (isHorizontal) {
                    const newTranslateX = event.translationX
                    // 根据位置限制拖拽方向
                    if (position === 'left' && newTranslateX > 0) {
                        translateX.value = newTranslateX
                    } else if (position === 'right' && newTranslateX < 0) {
                        translateX.value = newTranslateX
                    } else if (position === 'left' || position === 'right') {
                        translateX.value = newTranslateX
                    }
                } else {
                    const newTranslateY = event.translationY
                    // 根据位置限制拖拽方向
                    if (position === 'bottom' && newTranslateY > 0) {
                        translateY.value = newTranslateY
                    } else if (position === 'top' && newTranslateY < 0) {
                        translateY.value = newTranslateY
                    } else if (position === 'bottom' || position === 'top') {
                        translateY.value = newTranslateY
                    }
                }

                // 更新遮罩层透明度
                const currentOffset = isHorizontal ? translateX.value : translateY.value
                const opacity = interpolate(
                    Math.abs(currentOffset),
                    [0, Math.abs(maxOffset)],
                    [1, 0],
                    Extrapolation.CLAMP,
                )
                backdropOpacity.value = opacity
            })
            .onEnd((event) => {
                const velocity = isHorizontal ? event.velocityX : event.velocityY
                const translation = isHorizontal ? translateX.value : translateY.value

                // 判断是否应该关闭
                const shouldClose =
                    Math.abs(velocity) > swipeVelocityThreshold ||
                    Math.abs(translation) > Math.abs(maxOffset) * 0.5

                if (shouldClose) {
                    // 关闭动画
                    if (isHorizontal) {
                        translateX.value = withSpring(
                            maxOffset,
                            {
                                velocity: event.velocityX,
                                damping: 20,
                                stiffness: 90,
                            },
                            () => {
                                runOnJS(close)()
                            },
                        )
                    } else {
                        translateY.value = withSpring(
                            maxOffset,
                            {
                                velocity: event.velocityY,
                                damping: 20,
                                stiffness: 90,
                            },
                            () => {
                                runOnJS(close)()
                            },
                        )
                    }
                } else {
                    // 回弹动画
                    if (isHorizontal) {
                        translateX.value = withSpring(0, {
                            velocity: event.velocityX,
                            damping: 20,
                            stiffness: 90,
                        })
                    } else {
                        translateY.value = withSpring(0, {
                            velocity: event.velocityY,
                            damping: 20,
                            stiffness: 90,
                        })
                    }
                    backdropOpacity.value = withTiming(1, { duration: 200 })
                }
            })

        // 计算安全区域样式
        const safeAreaStyle = useMemo(() => {
            const safeStyle: any = {}
            if (Platform.OS === 'ios') {
                switch (position) {
                    case 'bottom':
                        safeStyle.paddingBottom = insets.bottom
                        break
                    case 'top':
                        safeStyle.paddingTop = insets.top
                        break
                    case 'left':
                    case 'right':
                        safeStyle.paddingTop = insets.top
                        safeStyle.paddingBottom = insets.bottom
                        break
                }
            }
            return safeStyle
        }, [position, insets])

        // 抽屉内容动画样式
        const drawerAnimatedStyle = useAnimatedStyle(() => {
            const baseStyle: any = {
                overflow: position === 'bottom' ? 'visible' : 'hidden',
            }

            switch (position) {
                case 'bottom':
                    baseStyle.transform = [{ translateY: translateY.value }]
                    baseStyle.bottom = 0
                    baseStyle.left = 0
                    baseStyle.right = 0
                    baseStyle.height = drawerHeight
                    baseStyle.borderTopLeftRadius = 20
                    baseStyle.borderTopRightRadius = 20
                    break
                case 'top':
                    baseStyle.transform = [{ translateY: translateY.value }]
                    baseStyle.top = 0
                    baseStyle.left = 0
                    baseStyle.right = 0
                    baseStyle.height = drawerHeight
                    baseStyle.borderBottomLeftRadius = 20
                    baseStyle.borderBottomRightRadius = 20
                    break
                case 'left':
                    baseStyle.transform = [{ translateX: translateX.value }]
                    baseStyle.left = 0
                    baseStyle.top = 0
                    baseStyle.bottom = 0
                    baseStyle.width = drawerWidth
                    baseStyle.borderTopRightRadius = 20
                    baseStyle.borderBottomRightRadius = 20
                    break
                case 'right':
                    baseStyle.transform = [{ translateX: translateX.value }]
                    baseStyle.right = 0
                    baseStyle.top = 0
                    baseStyle.bottom = 0
                    baseStyle.width = drawerWidth
                    baseStyle.borderTopLeftRadius = 20
                    baseStyle.borderBottomLeftRadius = 20
                    break
            }

            return baseStyle
        }, [position, drawerHeight, drawerWidth])

        // 遮罩层动画样式
        const backdropAnimatedStyle = useAnimatedStyle(() => {
            return {
                opacity: backdropOpacity.value,
            }
        })

        if (!visible) {
            return null
        }

        return (
            <Modal
                transparent
                visible={visible}
                animationType="none"
                onRequestClose={close}
                statusBarTranslucent={Platform.OS === 'android'}
            >
                <View style={styles.container}>
                    {/* 遮罩层 */}
                    {showBackdrop && (
                        <AnimatedPressable
                            style={[
                                styles.backdrop,
                                backdropAnimatedStyle,
                                { backgroundColor: backdropColor },
                                backdropStyle,
                            ]}
                            onPress={closeOnBackdropPress ? close : undefined}
                        />
                    )}

                    {/* 抽屉内容 */}
                    <GestureDetector gesture={pan}>
                        <Animated.View
                            style={[
                                styles.drawer,
                                drawerAnimatedStyle,
                                getPositionStyles(position),
                                safeAreaStyle,
                                style,
                            ]}
                        >
                            {showCloseButton && (
                                <Pressable
                                    style={styles.closeButton}
                                    onPress={close}
                                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                                >
                                    <CloseIcon />
                                </Pressable>
                            )}
                            {children}
                        </Animated.View>
                    </GestureDetector>
                </View>
            </Modal>
        )
    },
)

Drawer.displayName = 'Drawer'

// 根据位置获取样式（圆角已在动画样式中设置）
const getPositionStyles = (position: DrawerPosition) => {
    return {}
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    backdrop: {
        ...StyleSheet.absoluteFillObject,
    },
    drawer: {
        position: 'absolute',
        backgroundColor: '#1C1E20',
    },
    closeButton: {
        position: 'absolute',
        top: Platform.select({ ios: 16, android: 16, default: 16 }),
        right: Platform.select({ ios: 16, android: 16, default: 16 }),
        zIndex: 10,
        width: 24,
        height: 24,
        alignItems: 'center',
        justifyContent: 'center',
    },
})

export default Drawer

