import { reactive } from 'vue'

/**
 * Vue 3 composable for memoizing functions.
 * Works across components and SPA navigation (module-level singleton cache).
 *
 * Usage:
 * const { memoize, memoizeFull } = useMemoize()
 * const add10 = (n) => n + 10
 * const cachedAdd = memoize(add10)
 * cachedAdd(5) // calculates
 * cachedAdd(5) // returns cached result
 */
export function useMemoize() {
  // reactive singleton caches
  const cacheSingle = reactive({})
  const cacheMulti = reactive({})

  /**
   * Memoize a single-argument function.
   * @param {Function} fn - Function with one argument
   * @returns {Function} Memoized function
   */
  function memoize(fn) {
    return (arg) => {
      if (arg in cacheSingle) {
        // console.log('Fetching from cache')
        return cacheSingle[arg]
      }
      // console.log('Calculating result')
      const result = fn(arg)
      cacheSingle[arg] = result
      return result
    }
  }

  /**
   * Memoize a function with multiple arguments.
   * @param {Function} fn - Function with any number of arguments
   * @returns {Function} Memoized function
   */
  function memoizeFull(fn) {
    return (...args) => {
      const key = JSON.stringify(args)
      if (cacheMulti[key]) {
        // console.log('Fetching from cache for:', args)
        return cacheMulti[key]
      }

      const result = fn(...args)
      cacheMulti[key] = result
      return result
    }
  }

  /**
   * Optional: clear caches
   */
  function clearCache() {
    Object.keys(cacheSingle).forEach(k => delete cacheSingle[k])
    Object.keys(cacheMulti).forEach(k => delete cacheMulti[k])
  }

  return {
    memoize,
    memoizeFull,
    cacheSingle,
    cacheMulti,
    clearCache
  }
}
