import {Keyboard} from "react-native"
import {runOnJS, useAnimatedReaction} from "react-native-reanimated"

import {
    useBottomSheetToolboxInternalContext,
    useKeyboardHeightSharedValue,
    useKeyboardProgressSharedValue,
} from "../context"
import {normalizeSheetPosition, type SheetPosition} from "../utils"
import {useBottomSheetDirection} from "./use-bottom-sheet-direction"

const dismiss = () => {
    Keyboard.dismiss()
}

/**
 * Dismiss the keyboard if the bottom sheet moves downwardly beneath the keyboard.
 */
export function useBottomSheetKeyboardDismiss(extraBuffer?: SheetPosition) {
    const {
        isReadySharedValue,
        currentPositionSharedValue,
        childrenHeightSharedValue,
        wrapperHeightSharedValue,
        footerHeightSharedValue,
    } = useBottomSheetToolboxInternalContext()

    const keyboardHeightSharedValue = useKeyboardHeightSharedValue()
    const keyboardProgressSharedValue = useKeyboardProgressSharedValue()
    const directionSharedValue = useBottomSheetDirection()

    useAnimatedReaction(
        () => {
            if (!isReadySharedValue.get() || keyboardProgressSharedValue.get() !== 1) {
                return null
            }

            const normalizedBuffer = extraBuffer
                ? normalizeSheetPosition({
                      sheetPosition: extraBuffer,
                      childrenHeightSharedValue,
                      wrapperHeightSharedValue,
                      footerHeightSharedValue,
                  })
                : 0

            if (normalizedBuffer === null) return null

            const keyboardDismissTriggerHeight = keyboardHeightSharedValue.get() + normalizedBuffer

            return {
                keyboardDismissTriggerHeight,
                currentPosition: currentPositionSharedValue.get(),
                direction: directionSharedValue.get(),
            }
        },
        (result) => {
            if (result === null) return

            const {keyboardDismissTriggerHeight, currentPosition, direction} = result
            const shouldDismiss = currentPosition < keyboardDismissTriggerHeight && direction < 0
            if (shouldDismiss) {
                runOnJS(dismiss)()
            }
        },
        [
            extraBuffer,
            isReadySharedValue,
            currentPositionSharedValue,
            childrenHeightSharedValue,
            wrapperHeightSharedValue,
            directionSharedValue,
            keyboardHeightSharedValue,
            keyboardProgressSharedValue,
            footerHeightSharedValue,
        ]
    )
}
