/** Converts a boolean-like value to SQLite's 0/1 integer representation. */
export const boolToInt = (val: unknown) => (val ? 1 : 0);

/** Serialises an object to a JSON string, or returns null if the value is null/undefined. */
export const jsonOrNull = (val: unknown) => (val != null ? JSON.stringify(val) : null);

/** A map of field names to transform functions that handle special serialisation. */
export type TransformMap = Partial<Record<string, (val: unknown) => unknown>>;

/**
 * Applies a partial `updates` object onto an existing entity.
 *
 * - Fields absent from `updates` (undefined) are skipped entirely.
 * - Fields listed in `transforms` are passed through their transform function first.
 * - All other fields are written as-is, falling back to null when the value is null/undefined.
 */
export function applyUpdates<T extends object>(
  entity: T,
  updates: Partial<Record<string, unknown>>,
  transforms: TransformMap = {}
): void {
  const target = entity as unknown as Record<string, unknown>;

  for (const [key, value] of Object.entries(updates)) {
    if (value === undefined)
      continue;

    const transform = transforms[key];

    target[key] = transform ? transform(value) : (value ?? null);
  }
}
