import {type StyleProp, StyleSheet, type ViewStyle} from "react-native"
import Animated, {
    type AnimatedStyle,
    type SharedValue,
    useAnimatedStyle,
    useDerivedValue,
} from "react-native-reanimated"

import {
    useBottomSheetToolboxInternalContext,
    useKeyboardAwareSafeAreaBottomInset,
    useKeyboardHeightSharedValue,
} from "@attio/react-native-bottom-sheet-toolbox"

const styles = StyleSheet.create({
    container: {
        bottom: 0,
        opacity: 0,
        position: "absolute",
        width: "100%",
    },
})

export interface OverlayTextInputContainerProps {
    children: React.ReactNode
    keyboardAwareSafeAreaBottomInsetFallback: number
    minTextInputHeightSharedValue: SharedValue<number | null>
    topInsetSharedValue: SharedValue<number | null>
    bottomInsetSharedValue: SharedValue<number>

    style?: AnimatedStyle<StyleProp<ViewStyle>>
}

export function OverlayTextInputContainer({
    children,
    style,
    minTextInputHeightSharedValue,
    topInsetSharedValue,
    keyboardAwareSafeAreaBottomInsetFallback,
}: OverlayTextInputContainerProps) {
    const {isReadySharedValue, currentPositionSharedValue} = useBottomSheetToolboxInternalContext()

    const keyboardAwareSafeAreaBottomInsetSharedValue = useKeyboardAwareSafeAreaBottomInset(
        keyboardAwareSafeAreaBottomInsetFallback
    )
    const keyboardHeightSharedValue = useKeyboardHeightSharedValue()

    const bottomSharedValue = useDerivedValue(() => {
        const bottomInset = keyboardAwareSafeAreaBottomInsetSharedValue.get()
        const keyboardHeight = keyboardHeightSharedValue.get()
        const minTextInputHeight = minTextInputHeightSharedValue.get()
        const topInset = topInsetSharedValue.get()
        if (minTextInputHeight === null || topInset === null) return null

        const unclampedClosingOffset =
            currentPositionSharedValue.get() -
            minTextInputHeight -
            keyboardHeight -
            topInset -
            bottomInset
        const closingOffset = Math.min(0, unclampedClosingOffset)

        const bottom = keyboardHeight + closingOffset

        return bottomInset - bottom
    }, [
        keyboardAwareSafeAreaBottomInsetSharedValue,
        keyboardHeightSharedValue,
        currentPositionSharedValue,
        minTextInputHeightSharedValue,
        topInsetSharedValue,
    ])

    const animatedStyle = useAnimatedStyle(() => {
        const bottom = bottomSharedValue.get()
        if (bottom === null || !isReadySharedValue.get()) return {}

        const bottomInset = keyboardAwareSafeAreaBottomInsetSharedValue.get()

        return {
            opacity: 1,
            paddingBottom: bottomInset,
            transform: [{translateY: bottom}],
        }
    }, [isReadySharedValue, keyboardAwareSafeAreaBottomInsetSharedValue])

    return (
        <Animated.View style={[styles.container, style, animatedStyle]}>{children}</Animated.View>
    )
}
