import { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

/**
 * Portal component renders its children in a separate portal container appended to the document body.
 *
 * While `@gorhom/portal` works well for a lot of use-cases, there are some issues with it, particularly around
 * reading context values (see issues below). For web-only components, it is safe to replace `Portal` from `@gorhom/portal`
 * to `Portal` to solve such issues
 *
 * https://github.com/gorhom/react-native-portal/issues/34
 * https://github.com/gorhom/react-native-portal/issues/2
 * https://github.com/gorhom/react-native-portal/issues/3
 * https://github.com/gorhom/react-native-portal/issues/31
 *
 * @component
 * @param {object} props - The component props.
 * @param {React.ReactNode} props.children - The content to render within the portal.
 * @returns {React.ReactPortal} The React portal component.
 */

export const Portal = ({ children }) => {
  const [portalContainer, setPortalContainer] = useState(null)
  const isWebClient = typeof document !== 'undefined' && typeof window !== 'undefined'

  useEffect(() => {
    if (!isWebClient) {
      return
    }
    const container = document.createElement('div')
    document.body.appendChild(container)
    setPortalContainer(container)

    // eslint-disable-next-line consistent-return
    return () => {
      if (container && container.parentNode) {
        container.parentNode.removeChild(container)
      }
    }
  }, [isWebClient])

  if (!portalContainer || !isWebClient) return null

  return ReactDOM.createPortal(children, portalContainer)
}

Portal.propTypes = {
  /**
   * Content rendered into the app's portal host, outside the normal view hierarchy.
   */
  children: PropTypes.node.isRequired
}
