// @ts-nocheck
/**
 * 深度克隆壹個對象或數組
 * @param obj 要克隆的對象或數組
 * @returns 克隆後的對象或數組
 */
export function cloneDeep<T>(obj: any): T {
  // 如果傳入的對象為空，返回空
  if (obj === null) {
    return null as unknown as T;
  }

  // 如果傳入的對象是 Set 類型，則將其轉換為數組，並通過新的 Set 構造函數創建壹個新的 Set 對象
  if (obj instanceof Set) {
    return new Set([...obj]) as unknown as T;
  }

  // 如果傳入的對象是 Map 類型，則將其轉換為數組，並通過新的 Map 構造函數創建壹個新的 Map 對象
  if (obj instanceof Map) {
    return new Map([...obj]) as unknown as T;
  }

  // 如果傳入的對象是 WeakMap 類型，則直接用傳入的 WeakMap 對象進行賦值
  if (obj instanceof WeakMap) {
    let weakMap = new WeakMap();
    weakMap = obj;
    return weakMap as unknown as T;
  }

  // 如果傳入的對象是 WeakSet 類型，則直接用傳入的 WeakSet 對象進行賦值
  if (obj instanceof WeakSet) {
    let weakSet = new WeakSet();
    weakSet = obj;
    return weakSet as unknown as T;
  }

  // 如果傳入的對象是 RegExp 類型，則通過新的 RegExp 構造函數創建壹個新的 RegExp 對象
  if (obj instanceof RegExp) {
    return new RegExp(obj) as unknown as T;
  }

  // 如果傳入的對象是 undefined 類型，則返回 undefined
  if (typeof obj === 'undefined') {
    return undefined as unknown as T;
  }

  // 如果傳入的對象是數組，則遞歸調用 cloneDeep 函數對數組中的每個元素進行克隆
  if (Array.isArray(obj)) {
    return obj.map(cloneDeep) as unknown as T;
  }

  // 如果傳入的對象是 Date 類型，則通過新的 Date 構造函數創建壹個新的 Date 對象
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T;
  }

  // 如果傳入的對象是普通對象，則使用遞歸調用 cloneDeep 函數對對象的每個屬性進行克隆
  if (typeof obj === 'object') {
    const newObj: any = {};
    for (const [key, value] of Object.entries(obj)) {
      newObj[key] = cloneDeep(value);
    }
    const symbolKeys = Object.getOwnPropertySymbols(obj);
    for (const key of symbolKeys) {
      newObj[key] = cloneDeep(obj[key]);
    }
    return newObj;
  }

  // 如果傳入的對象是基本數據類型（如字符串、數字等），則直接返回
  return obj;
}

// 示例使用

// // 克隆壹個對象
// const obj = { name: 'John', age: 30 };
// const clonedObj = cloneDeep(obj);

// console.log(clonedObj); // 輸出: { name: 'John', age: 30 }
// console.log(clonedObj === obj); // 輸出: false (副本與原對象是獨立的)

// // 克隆壹個數組
// const arr = [1, 2, 3];
// const clonedArr = cloneDeep(arr);

// console.log(clonedArr); // 輸出: [1, 2, 3]
// console.log(clonedArr === arr); // 輸出: false (副本與原數組是獨立的)

// // 克隆壹個包含嵌套對象的對象
// const person = {
//   name: 'Alice',
//   age: 25,
//   address: {
//     city: 'New York',
//     country: 'USA',
//   },
// };
// const clonedPerson = cloneDeep(person);

// console.log(clonedPerson); // 輸出: { name: 'Alice', age: 25, address: { city: 'New York', country: 'USA' } }
// console.log(clonedPerson === person); // 輸出: false (副本與原對象是獨立的)
// console.log(clonedPerson.address === person.address); // 輸出: false (嵌套對象的副本也是獨立的)