/**
 * 过滤对象中的空值属性
 * @param sourceObject 源对象
 * @returns 只包含非空值属性的新对象
 *
 * @description 该函数会遍历源对象的所有属性，只保留非空值的属性。
 * 空值定义为：null、undefined、空字符串('')
 * 支持嵌套对象的递归处理
 */
export function filterEmptyValues<T extends object>(sourceObject: T): Partial<T> {
  const result: Partial<T> = {};

  // 遍历源对象的所有属性
  Object.keys(sourceObject).forEach(key => {
    const value = (sourceObject as any)[key];

    // 检查值是否不为空
    if (value !== null && value !== undefined && value !== '') {
      // 如果是对象且不是数组，递归处理
      if (typeof value === 'object' && !Array.isArray(value)) {
        // 递归过滤嵌套对象
        const filteredNestedObject = filterEmptyValues(value);
        // 只有当过滤后的嵌套对象有属性时才添加
        if (Object.keys(filteredNestedObject).length > 0) {
          (result as any)[key] = filteredNestedObject;
        }
      } else {
        // 对于非对象类型或数组，直接添加
        (result as any)[key] = value;
      }
    }
  });

  return result;
}

/**
 * 增强版过滤对象空值属性
 * @param sourceObject 源对象
 * @param options 过滤选项
 * @returns 过滤后的新对象
 *
 * @description 提供更灵活的空值过滤配置，可自定义空值判断逻辑
 */
export function filterEmptyValuesAdvanced<T extends object>(
  sourceObject: T,
  options: {
    // 是否将空数组视为空值
    treatEmptyArrayAsEmpty?: boolean;
    // 是否将空对象视为空值
    treatEmptyObjectAsEmpty?: boolean;
    // 是否将0视为空值
    treatZeroAsEmpty?: boolean;
    // 是否将false视为空值
    treatFalseAsEmpty?: boolean;
  } = {}
): Partial<T> {
  const {
    treatEmptyArrayAsEmpty = false,
    treatEmptyObjectAsEmpty = false,
    treatZeroAsEmpty = false,
    treatFalseAsEmpty = false
  } = options;

  const result: Partial<T> = {};

  Object.keys(sourceObject).forEach(key => {
    const value = (sourceObject as any)[key];

    // 基本空值检查
    let isEmpty = value === null || value === undefined || value === '';

    // 根据选项进行额外的空值检查
    if (!isEmpty && treatZeroAsEmpty && value === 0) {
      isEmpty = true;
    }

    if (!isEmpty && treatFalseAsEmpty && value === false) {
      isEmpty = true;
    }

    if (!isEmpty && treatEmptyArrayAsEmpty && Array.isArray(value) && value.length === 0) {
      isEmpty = true;
    }

    if (!isEmpty && treatEmptyObjectAsEmpty && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
      isEmpty = true;
    }

    // 如果值不为空，处理并添加到结果中
    if (!isEmpty) {
      if (typeof value === 'object' && !Array.isArray(value)) {
        const filteredNestedObject = filterEmptyValuesAdvanced(value, options);
        if (Object.keys(filteredNestedObject).length > 0) {
          (result as any)[key] = filteredNestedObject;
        }
      } else {
        (result as any)[key] = value;
      }
    }
  });

  return result;
}

/**
 * 从源对象复制非空值到目标对象
 * @param source 源对象
 * @param target 目标对象
 * @returns 更新后的目标对象
 */
export function copyNonEmptyValues<T extends object, U extends object>(source: T, target: U): U & Partial<T> {
  const filteredValues = filterEmptyValues(source);
  return Object.assign(target, filteredValues) as U & Partial<T>;
}
