import { useLayoutEffect, useRef } from 'react'

import { useForceRerender } from './useForceRerender.ts'

interface UseFirstRenderOptions {
  /** Callback to run on first render. */
  callback?: () => void
  /**
   * If true, immediately triggers a re-render after the first render. Otherwise, the returned
   * boolean will not update until the component rerenders for some other reason.
   *
   * @default false
   */
  immediatelyRerender?: boolean | undefined
}

export function useFirstRender(callback?: () => void): boolean
export function useFirstRender(options: UseFirstRenderOptions): boolean
export function useFirstRender(callbackOrOptions?: (() => void) | UseFirstRenderOptions) {
  const options = typeof callbackOrOptions === 'function' ? undefined : callbackOrOptions
  const callback = typeof callbackOrOptions === 'function' ? callbackOrOptions : options?.callback

  const firstRender = useRef(true)
  const [rerender] = useForceRerender()

  useLayoutEffect(() => {
    if (!firstRender.current) return
    firstRender.current = false
    callback?.()
    if (options?.immediatelyRerender) {
      rerender()
    }
    // oxlint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  return firstRender.current
}
