/**
 * Gets a nested property value from an object using dot notation
 * @param obj - The object to get the value from
 * @param path - The dot-separated path (e.g., "_source.meta.test")
 * @returns The value at the path or undefined if not found
 */
const getNestedValue = (obj: Record<string, any>, path: string): any => {
  return path.split(".").reduce((current, key) => {
    return current && typeof current === "object" ? current[key] : undefined
  }, obj)
}

/**
 * Replaces placeholders in a URL template with values from an object
 * Supports both simple properties (:_id) and nested properties (:_source.meta.test)
 * @param template - URL template with placeholders like "/cluster/:_id" or "/test/:_source.meta.test"
 * @param params - Object containing replacement values
 * @returns URL string with placeholders replaced, unmatched placeholders remain unchanged
 */
export const replaceUrlParams = (
  template: string,
  params: Record<string, any>,
): string => {
  return template.replace(/:([a-zA-Z_][\w.]*)/g, (match, paramPath) => {
    const value = getNestedValue(params, paramPath)
    return value !== undefined ? String(value) : match
  })
}

// Curried version if you prefer functional style
export const replaceUrlParamsCurried =
  (template: string) =>
  (params: Record<string, any>): string => {
    return replaceUrlParams(template, params)
  }
