import { isRef, toValue, type MaybeRefOrGetter } from "vue"
import type {
  CustomStoreActionParams,
  QueryParamsInput,
} from "@racletteCore/types"
import { isDevelopmentMode } from "@racletteCore/helpers/devMode"
import log from "@racletteCore/lib/logger"
import type { VueQueryParamsInput } from "../types/DataApi"

function isPlainParamsObject(
  value: unknown,
): value is CustomStoreActionParams {
  return value != null && typeof value === "object" && !Array.isArray(value)
}

function warnInvalidQueryParams(context: string, value: unknown): void {
  if (!isDevelopmentMode()) return
  const kind =
    value == null ? String(value) : Array.isArray(value) ? "array" : typeof value
  log.warning(
    "Invalid query params",
    `${context}: expected a plain object, got ${kind}. Using {}.`,
  )
}

/**
 * Normalize Vue reactive params into core {@link QueryParamsInput}:
 * a plain object snapshot, or a subscriber re-read on each `execute()`.
 */
export function toQueryParamsSource(
  params?: VueQueryParamsInput,
): QueryParamsInput {
  if (params == null) return {}

  if (typeof params === "function" || isRef(params)) {
    return () => {
      const resolved = toValue(params as MaybeRefOrGetter)
      if (isPlainParamsObject(resolved)) return resolved
      warnInvalidQueryParams("Reactive params subscriber", resolved)
      return {}
    }
  }

  if (isPlainParamsObject(params)) return params

  warnInvalidQueryParams("Query params", params)
  return {}
}
