import { ref, watch } from 'vue'
import { useActive } from './useActive'

import type { Ref } from 'vue'

type Result<R> = [state: Ref<R>, update: () => void]
export function useRealtime<R>(fun: () => Promise<R>): Result<R | void>
export function useRealtime<R>(fun: () => Promise<R>, initial: R): Result<R>
export function useRealtime<R>(fun: () => R): Result<R | void>
export function useRealtime<R>(fun: () => R, initial: R): Result<R>
export function useRealtime<R>(fun: () => Promise<R> | R, initial?: R) {
  const state = ref<R>()
  state.value = initial

  const update = () => {
    const result = fun()
    if (result instanceof Promise) {
      result.then(newState => (state.value = newState))
    } else {
      state.value = result
    }
  }

  const active = useActive()
  watch(active, () => active.value && update(), { immediate: true })
  return [state, update]
}
