import React from "react"

import type {BottomSheetToolboxProps, BottomSheetToolboxRef} from "../bottom-sheet-toolbox"
import {ModalPortal} from "./modal-portal"

export interface BottomSheetModalWrapperRef {
    open: () => void
    close: () => void
}

interface BottomSheetModalWrapperProps<
    T extends Pick<BottomSheetToolboxRef, "close"> = BottomSheetToolboxRef,
> {
    children: (
        sheetProps: Required<Pick<BottomSheetToolboxProps, "onClose">> & {
            ref: React.ForwardedRef<T>
        }
    ) => React.ReactNode
    onClose: BottomSheetToolboxProps["onClose"] | null
    openSheetOnMount?: boolean
    ref?: React.ForwardedRef<BottomSheetModalWrapperRef>
}

export function BottomSheetModalWrapper<
    T extends Pick<BottomSheetToolboxRef, "close"> = BottomSheetToolboxRef,
>({ref, children, openSheetOnMount = false, onClose}: BottomSheetModalWrapperProps<T>) {
    const [isSheetOpen, setIsSheetOpen] = React.useState(openSheetOnMount)
    const openSheet = React.useCallback(() => setIsSheetOpen(true), [])
    const closeSheet = React.useCallback(() => setIsSheetOpen(false), [])

    const currentOnClose = React.useMemo(() => onClose ?? (() => {}), [onClose])
    const onSheetClose = React.useCallback(() => {
        closeSheet()
        currentOnClose()
    }, [closeSheet, currentOnClose])

    const innerRef = React.useRef<T>(null)
    const closeSheetPreserveAnimation = React.useCallback(() => {
        if (innerRef.current) {
            innerRef.current.close()
        } else {
            setIsSheetOpen(false)
        }
    }, [])

    React.useImperativeHandle(
        ref,
        () => ({
            open: openSheet,
            close: closeSheetPreserveAnimation,
        }),
        [openSheet, closeSheetPreserveAnimation]
    )

    return (
        <ModalPortal visible={isSheetOpen} onDismiss={closeSheet} onRequestClose={closeSheet}>
            {children({ref: innerRef, onClose: onSheetClose})}
        </ModalPortal>
    )
}
