import { useCallback, useRef, useSyncExternalStore } from 'react'
import type { CameraOrientation } from '../specs/common-types/CameraOrientation'
import type { OrientationSource } from '../specs/common-types/OrientationSource'
import { useOrientationManager } from './internal/useOrientationManager'

/**
 * Reactively use the current {@linkcode source} {@linkcode CameraOrientation}.
 * - {@linkcode OrientationSource | 'interface'} will listen to UI-orientation.
 * - {@linkcode OrientationSource | 'device'} will listen to physical phone orientation.
 * - `undefined` will return `undefined` and not listen to anything.
 *
 * @example
 * ```ts
 * const orientation = useOrientation('device')
 * // orientation: 'up' | 'right' | 'down' | 'left' | undefined
 * ```
 */
export function useOrientation(
  source: OrientationSource | undefined,
): CameraOrientation | undefined {
  const orientationManager = useOrientationManager(source)
  const currentOrientation = useRef(orientationManager?.currentOrientation)

  const subscribe = useCallback(
    (onStoreChange: () => void) => {
      if (orientationManager == null) return () => {}

      orientationManager.startOrientationUpdates((orientation) => {
        currentOrientation.current = orientation
        onStoreChange()
      })
      return () => orientationManager.stopOrientationUpdates()
    },
    [orientationManager],
  )
  const getSnapshot = useCallback(() => currentOrientation.current, [])
  return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)
}
