import React from 'react'
import PropTypes from 'prop-types'
import { Platform } from 'react-native'

const HydrationContext = React.createContext()
const isSSR = typeof window === 'undefined'
const hasWebStyleTag = () => {
  if (isSSR || Platform.OS !== 'web' || typeof document !== 'object') {
    return false
  }
  return Boolean(document?.getElementById('react-native-stylesheet'))
}

/**
 * Returns true if this render cycle is the hydration of existing SSR content.
 *
 * Use this when changing how content renders based on data that is instantly available
 * during the very first client-side render or hydration, but not available on the server,
 * to ensure no changes happen until the original SSR DOM has been hydrated.
 */
export const useHydrationContext = () => React.useContext(HydrationContext)

/**
 * Allows components and hooks to observe if SSR hydration is currently in progress
 * and if so, to re-render with content that differs to the server when it is complete.
 */
export const HydrationProvider = ({ children }) => {
  const [hasMounted, setHasMounted] = React.useState(false)
  React.useEffect(() => {
    setHasMounted(true)
  }, [])

  // If we've got a HydrationProvider inside a HydrationProvider somehow, defer to the top one
  const valueFromAncestor = useHydrationContext()

  const isHydrating = valueFromAncestor ?? Boolean(!hasMounted && hasWebStyleTag())
  return <HydrationContext.Provider value={isHydrating}>{children}</HydrationContext.Provider>
}

HydrationProvider.propTypes = {
  children: PropTypes.node
}
