/**
 * Deep key-casing converters for JSON payloads.
 *
 * - `toSnakeCase(obj)` — camelCase → snake_case (outgoing to backend)
 * - `toCamelCase(obj)` — snake_case → camelCase (incoming from backend)
 *
 * Only object **keys** are converted — values are left untouched.
 * Handles nested objects, arrays, null, and primitives.
 *
 * @see AI_REFACTOR_PLAN.md — Phase 1, Step 1.1
 */

// ---------------------------------------------------------------------------
// Key converters
// ---------------------------------------------------------------------------

/** `fooBarBaz` → `foo_bar_baz` */
function keyToSnake(key: string): string {
  return key.replace(/([A-Z])/g, '_$1').toLowerCase();
}

/** `foo_bar_baz` → `fooBarBaz` */
function keyToCamel(key: string): string {
  return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());
}

// ---------------------------------------------------------------------------
// Deep converters
// ---------------------------------------------------------------------------

function deepConvertKeys(obj: unknown, convertKey: (k: string) => string): unknown {
  if (obj === null || obj === undefined) return obj;
  if (Array.isArray(obj)) return obj.map((item) => deepConvertKeys(item, convertKey));
  if (typeof obj === 'object' && !(obj instanceof Date)) {
    const result: Record<string, unknown> = {};
    for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {
      result[convertKey(key)] = deepConvertKeys(value, convertKey);
    }
    return result;
  }
  return obj;
}

/**
 * Deep-convert all object keys from camelCase to snake_case.
 * Used for outgoing JSON payloads to the Python backend.
 */
export function toSnakeCase<T = unknown>(obj: unknown): T {
  return deepConvertKeys(obj, keyToSnake) as T;
}

/**
 * Deep-convert all object keys from snake_case to camelCase.
 * Used for incoming JSON payloads from the Python backend.
 */
export function toCamelCase<T = unknown>(obj: unknown): T {
  return deepConvertKeys(obj, keyToCamel) as T;
}
