'use client'

import React from 'react'

/**
 * useSlideTransition
 *
 * Small state machine for mount/unmount + transition stages.
 *
 * @param params.open - whether the panel should be open
 * @param params.duration - animation duration in ms (default 400)
 */
export const useSlideTransition = ({
  open,
  duration = 400
}: {
  open: boolean
  duration?: number
}): {
  mounted: boolean
  stage: 'entering' | 'entered' | 'exiting' | 'exited'
  duration: number
} => {
  const [stage, setStage] = React.useState<
    'entering' | 'entered' | 'exiting' | 'exited'
  >(() => (open ? 'entering' : 'exited'))

  React.useEffect(() => {
    let enterTimeout: number | undefined
    let finishEnterRAF: number | undefined
    let exitTimeout: number | undefined

    if (open) {
      if (stage === 'exited') {
        setStage('entering')
        finishEnterRAF = window.requestAnimationFrame(() => {
          enterTimeout = window.setTimeout(() => setStage('entered'), 20)
        })
      } else if (stage === 'exiting') {
        setStage('entering')
        finishEnterRAF = window.requestAnimationFrame(() => {
          enterTimeout = window.setTimeout(() => setStage('entered'), 20)
        })
      } else if (stage === 'entering') {
        enterTimeout = window.setTimeout(() => setStage('entered'), duration + 20)
      }
    } else {
      if (stage === 'entered' || stage === 'entering') {
        setStage('exiting')
        exitTimeout = window.setTimeout(() => setStage('exited'), duration)
      }
    }

    return () => {
      if (enterTimeout) window.clearTimeout(enterTimeout)
      if (exitTimeout) window.clearTimeout(exitTimeout)
      if (finishEnterRAF) window.cancelAnimationFrame(finishEnterRAF)
    }
    // depend on open & duration only (stage handled internally)
  }, [open, duration])

  return {
    mounted: stage !== 'exited',
    stage,
    duration
  }
}
