import * as React from "react"
import {type StyleProp, StyleSheet, View, type ViewStyle} from "react-native"
import Animated from "react-native-reanimated"

import {useBottomSheetToolboxInternalContext} from "../context"
import {useAnimatedSheetStyle} from "../hooks/use-animated-sheet-style"

// The sheet can be dragged outside of the wrapper's bounds.
// In such case, we need to make sure that the sheet is still visible.
// To do so, we set the height to something arbitrarily larger than 100%.
// Then proportionally set the inner height to the real height.
const SHEET_HEIGHT = "200%"
const SHEET_INNER_HEIGHT = "100%"

const styles = StyleSheet.create({
    sheet: {
        height: SHEET_HEIGHT,
        opacity: 0,
        position: "absolute",
        top: 0,
        width: "100%",
    },
    sheetInner: {
        maxHeight: SHEET_INNER_HEIGHT,
        width: "100%",
    },
})

export interface BottomSheetToolboxSheetProps extends React.PropsWithChildren {
    style?: StyleProp<Omit<ViewStyle, keyof (typeof styles)["sheet"]>>
}

export function BottomSheetToolboxSheet({children, style}: BottomSheetToolboxSheetProps) {
    const {childrenHeightSharedValue} = useBottomSheetToolboxInternalContext()

    const unmountFn = () => {
        childrenHeightSharedValue.set(null)
    }
    const onUnmountRef = React.useRef(unmountFn)
    onUnmountRef.current = unmountFn

    React.useLayoutEffect(() => () => onUnmountRef.current(), [])

    const animatedSheetStyle = useAnimatedSheetStyle()

    return (
        <Animated.View style={[styles.sheet, animatedSheetStyle, style]}>
            <View
                onLayout={(evt) => {
                    childrenHeightSharedValue.set(
                        evt.nativeEvent.layout.height === 0 ? null : evt.nativeEvent.layout.height
                    )
                }}
                style={styles.sheetInner}
            >
                {children}
            </View>
        </Animated.View>
    )
}
