import { mergician, type MergicianOptions } from "mergician";
import { mergicianSettings } from "./constants";

/**
 * Deep merge two objects
 * @param target The target object that will be merged into and returned as the result, which will be modified by merging properties from the source object
 * @param source The source object whose properties will be merged into the target object
 * @param dedupeArrays A boolean flag indicating whether arrays should be deduplicated when merging (default is true)
 * @returns The merged object, which is the same as the target object after merging properties from the source object, with nested objects merged recursively and arrays concatenated and optionally deduplicated
 */
export function deepMerge<T extends Record<keyof T, any>>(
    target: Partial<T>,
    source: Partial<T>,
    mergeSettings?: MergicianOptions
): T {
    const settings = { ...mergicianSettings, ...(mergeSettings ?? {}) };
    const merger = mergician(settings);
    return merger(target, source);
}
