import { useState, useRef, useEffect } from 'react'
import {
    View,
    Text,
    StyleSheet,
    Pressable,
    Modal,
    FlatList,
    TouchableWithoutFeedback,
    LayoutChangeEvent,
    Platform,
    useWindowDimensions,
} from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { DownArrowIcon } from '@/components/icon'

export interface DropdownOption<T = string> {
    label: string
    value: T
    disabled?: boolean
}

export interface DropdownProps<T = string> {
    /**
     * 选项列表
     */
    options: DropdownOption<T>[]
    /**
     * 当前选中的值
     */
    value?: T
    /**
     * 选择回调
     */
    onSelect?: (value: T, option: DropdownOption<T>) => void
    /**
     * 占位符文本
     */
    placeholder?: string
    /**
     * 是否禁用
     */
    disabled?: boolean
    /**
     * 自定义触发按钮渲染
     */
    renderTrigger?: (selectedOption: DropdownOption<T> | undefined, isOpen: boolean, toggle: () => void) => React.ReactNode
    /**
     * 下拉列表的最大高度
     */
    maxHeight?: number
    /**
     * 下拉菜单距离触发按钮的垂直偏移（默认4px）
     */
    offsetTop?: number
    /**
     * 自定义样式
     */
    style?: any
    /**
     * 触发按钮样式
     */
    triggerStyle?: any
    /**
     * 下拉列表样式
     */
    dropdownStyle?: any
    /**
     * 选项项样式
     */
    optionStyle?: any
    /**
     * 选项文本样式
     */
    optionTextStyle?: any
    /**
     * 自定义选项渲染函数
     */
    renderOption?: (option: DropdownOption<T>, isSelected: boolean) => React.ReactNode
}

export default function Dropdown<T = string>({
    options,
    value,
    onSelect,
    placeholder = '请选择',
    disabled = false,
    renderTrigger,
    maxHeight = 200,
    offsetTop = 4,
    style,
    triggerStyle,
    dropdownStyle,
    optionStyle,
    optionTextStyle,
    renderOption,
}: DropdownProps<T>) {
    const [isOpen, setIsOpen] = useState(false)
    const [triggerLayout, setTriggerLayout] = useState({ x: 0, y: 0, width: 0, height: 0 })
    const triggerRef = useRef<View>(null)
    const layoutRef = useRef({ width: 0, height: 0 })
    const { width: screenWidth } = useWindowDimensions()
    const insets = useSafeAreaInsets()

    // 获取当前选中的选项
    const selectedOption = options.find(option => option.value === value)

    // 测量触发按钮的位置（跨平台兼容）
    const measureTrigger = () => {
        if (!triggerRef.current) return
        
        if (Platform.OS === 'android') {
            // Android 上使用 measure 方法，它返回相对于父组件的坐标
            triggerRef.current.measure((_x, _y, width, height, pageX, pageY) => {
                const finalWidth = width || layoutRef.current.width || 200
                const finalHeight = height || layoutRef.current.height || 40
                // pageY 在 Android 上已经包含了状态栏高度，所以直接使用
                setTriggerLayout({ 
                    x: pageX, 
                    y: pageY, 
                    width: finalWidth, 
                    height: finalHeight 
                })
            })
        } else {
            // iOS 和 Web 使用 measureInWindow
            triggerRef.current.measureInWindow((x, y, width, height) => {
                const finalWidth = width || layoutRef.current.width || 200
                const finalHeight = height || layoutRef.current.height || 40
                
                if (Platform.OS === 'web' && (width === 0 || height === 0)) {
                    // Web 平台使用 measure 作为后备
                    triggerRef.current?.measure((_x, _y, w, h, pageX, pageY) => {
                        setTriggerLayout({ 
                            x: pageX || x, 
                            y: pageY || y, 
                            width: w || finalWidth, 
                            height: h || finalHeight 
                        })
                    })
                } else {
                    setTriggerLayout({ 
                        x, 
                        y, 
                        width: finalWidth, 
                        height: finalHeight 
                    })
                }
            })
        }
    }

    // 测量触发按钮的位置
    const handleTriggerLayout = (event: LayoutChangeEvent) => {
        const { width, height } = event.nativeEvent.layout
        layoutRef.current = { width, height }
        // 延迟测量以确保布局已完成
        setTimeout(() => {
            measureTrigger()
        }, 0)
    }

    // 处理选项选择
    const handleSelect = (option: DropdownOption<T>) => {
        if (option.disabled) return
        onSelect?.(option.value, option)
        setIsOpen(false)
    }

    // 切换下拉菜单显示状态
    const toggleDropdown = () => {
        if (disabled) return
        // 在打开时重新测量位置
        if (!isOpen) {
            // 使用 setTimeout 确保在打开前完成测量
            // Android 上需要稍微延迟以确保测量准确
            const delay = Platform.OS === 'android' ? 50 : 0
            setTimeout(() => {
                measureTrigger()
            }, delay)
        }
        setIsOpen(!isOpen)
    }

    // 当打开时，重新测量位置（处理滚动等情况）
    useEffect(() => {
        if (isOpen) {
            // Android 上需要稍微延迟以确保测量准确
            const delay = Platform.OS === 'android' ? 50 : 0
            setTimeout(() => {
                measureTrigger()
            }, delay)
        }
    }, [isOpen])

    // 关闭下拉菜单
    const closeDropdown = () => {
        setIsOpen(false)
    }

    // 默认触发按钮渲染
    const defaultTrigger = (
        <Pressable
            style={[styles.trigger, triggerStyle, disabled && styles.triggerDisabled]}
            onPress={toggleDropdown}
            disabled={disabled}
        >
            <Text style={[styles.triggerText, !selectedOption && styles.triggerTextPlaceholder]}>
                {selectedOption ? selectedOption.label : placeholder}
            </Text>
            <View style={[styles.arrowIcon, isOpen && styles.arrowIconRotated]}>
                <DownArrowIcon />
            </View>
        </Pressable>
    )

    return (
        <View style={[styles.container, style]} ref={triggerRef} onLayout={handleTriggerLayout}>
            {renderTrigger ? renderTrigger(selectedOption, isOpen, toggleDropdown) : defaultTrigger}

            <Modal
                visible={isOpen}
                transparent
                animationType="fade"
                onRequestClose={closeDropdown}
            >
                <TouchableWithoutFeedback onPress={closeDropdown}>
                    <View style={styles.modalOverlay}>
                        <TouchableWithoutFeedback>
                            {(() => {
                                const dropdownWidth = (dropdownStyle as any)?.minWidth || (dropdownStyle as any)?.width || Math.max(triggerLayout.width, 200)
                                const hasRightAlignment = (dropdownStyle as any)?.right !== undefined
                                const rightValue = (dropdownStyle as any)?.right
                                const calculatedLeft = hasRightAlignment 
                                    ? screenWidth - (rightValue || 0) - dropdownWidth
                                    : triggerLayout.x
                                
                                // 从 dropdownStyle 中移除 right，避免样式冲突
                                const { right, ...restDropdownStyle } = dropdownStyle || {}
                                
                                return (
                                    <View
                                        style={[
                                            styles.dropdown,
                                            {
                                                top: triggerLayout.y + triggerLayout.height + offsetTop,
                                                left: calculatedLeft,
                                                width: dropdownWidth,
                                                maxHeight,
                                            },
                                            restDropdownStyle,
                                        ]}
                                    >
                                <FlatList
                                    data={options}
                                    keyExtractor={(item, index) => `option-${index}-${String(item.value)}`}
                                    renderItem={({ item }) => {
                                        const isSelected = item.value === value
                                        if (renderOption) {
                                            return (
                                                <Pressable
                                                    style={[
                                                        styles.option,
                                                        isSelected && styles.optionSelected,
                                                        item.disabled && styles.optionDisabled,
                                                        optionStyle,
                                                    ]}
                                                    onPress={() => handleSelect(item)}
                                                    disabled={item.disabled}
                                                >
                                                    {renderOption(item, isSelected)}
                                                </Pressable>
                                            )
                                        }
                                        return (
                                            <Pressable
                                                style={[
                                                    styles.option,
                                                    isSelected && styles.optionSelected,
                                                    item.disabled && styles.optionDisabled,
                                                    optionStyle,
                                                ]}
                                                onPress={() => handleSelect(item)}
                                                disabled={item.disabled}
                                            >
                                                <Text
                                                    style={[
                                                        styles.optionText,
                                                        isSelected && styles.optionTextSelected,
                                                        item.disabled && styles.optionTextDisabled,
                                                        optionTextStyle,
                                                    ]}
                                                >
                                                    {item.label}
                                                </Text>
                                            </Pressable>
                                        )
                                    }}
                                    showsVerticalScrollIndicator={false}
                                />
                                    </View>
                                )
                            })()}
                        </TouchableWithoutFeedback>
                    </View>
                </TouchableWithoutFeedback>
            </Modal>
        </View>
    )
}

const styles = StyleSheet.create({
    container: {
        position: 'relative',
    },
    trigger: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        paddingHorizontal: 12,
        paddingVertical: 8,
        borderRadius: 8,
        backgroundColor: '#272A30',
        minHeight: 40,
    },
    triggerDisabled: {
        opacity: 0.5,
    },
    triggerText: {
        color: '#F5F5F5',
        fontSize: 14,
        fontWeight: '500',
        flex: 1,
    },
    triggerTextPlaceholder: {
        color: '#ABABAB',
    },
    arrowIcon: {
        marginLeft: 8,
        transform: [{ rotate: '0deg' }],
    },
    arrowIconRotated: {
        transform: [{ rotate: '180deg' }],
    },
    modalOverlay: {
        flex: 1,
        backgroundColor: 'rgba(0, 0, 0, 0.3)',
    },
    dropdown: {
        position: 'absolute',
        backgroundColor: '#272A30',
        borderRadius: 12,
        overflow: 'hidden',
        ...Platform.select({
            ios: {
                shadowColor: '#000',
                shadowOffset: {
                    width: 0,
                    height: 4,
                },
                shadowOpacity: 0.3,
                shadowRadius: 8,
            },
            android: {
                elevation: 8,
            },
            web: {
                shadowColor: '#000',
                shadowOffset: {
                    width: 0,
                    height: 4,
                },
                shadowOpacity: 0.3,
                shadowRadius: 8,
                boxShadow: '0 4px 8px rgba(0, 0, 0, 0.3)',
            },
        }),
    },
    option: {
        paddingHorizontal: 16,
        paddingVertical: 12,
    },
    optionSelected: {
        backgroundColor: '#3A3D42',
    },
    optionDisabled: {
        opacity: 0.5,
    },
    optionText: {
        color: '#F5F5F5',
        fontSize: 14,
        fontWeight: '400',
    },
    optionTextSelected: {
        color: '#FFCF00',
        fontWeight: '500',
    },
    optionTextDisabled: {
        color: '#ABABAB',
    },
})

