/**
 * 深度去除对象/数组中所有字符串的前后空格，并尽量避免破坏非“普通对象”的结构（例如 Dayjs 实例）。
 *
 * 该函数会“就地修改”传入的 model（适配 ant-design-vue 的表单 v-model/validate 习惯）。
 */

type AnyRecord = Record<string, unknown>;

const isPlainObject = (val: unknown): val is AnyRecord => {
  if (val === null || typeof val !== 'object') return false;
  const proto = Object.getPrototypeOf(val);
  return proto === Object.prototype || proto === null;
};

const walk = (val: unknown, seen: WeakSet<object>): unknown => {
  if (typeof val === 'string') {
    return val.trim();
  }

  if (Array.isArray(val)) {
    for (let i = 0; i < val.length; i++) {
      val[i] = walk(val[i], seen) as any;
    }
    return val;
  }

  if (val && typeof val === 'object') {
    // 仅处理普通对象；其余对象（如 Date/Dayjs/自定义 class）保持原样
    if (!isPlainObject(val)) return val;
    if (seen.has(val)) return val;
    seen.add(val);

    for (const key of Object.keys(val)) {
      (val as AnyRecord)[key] = walk((val as AnyRecord)[key], seen);
    }
    return val;
  }

  return val;
};

export function trimFormModel<T>(model: T): T {
  // 普通对象/数组一般不会包含循环引用，但这里做个保护
  const seen = new WeakSet<object>();
  return walk(model, seen) as T;
}

