/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2023-02-20 14:31:06
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2025-02-28 10:19:30
 * @FilePath: /BudgetManaSystem/src/utils/tooljs.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */


import axios from 'axios';



let parent: any = undefined;

export const getDeepestTreeData: any = (tree: any, childrenName: string) => {

  if (tree[`${childrenName}`] && tree[`${childrenName}`].length > 0) {
    parent = tree;
    return getDeepestTreeData(tree[`${childrenName}`][0], childrenName)
  }

  return [tree, parent]
}


//找出所有的子节点(不包含有child的节点)
export const getChilds = (treeData: any, childKeyName: string) => {
  let result: any[] = [];
  const looper = (node: any) => {
    if (node[`${childKeyName}`] && treeData[`${childKeyName}`].length > 0) {
      for (const child of node[`${childKeyName}`]) {
         if(child[`${childKeyName}`]&&child[`${childKeyName}`].length>0){
              looper(child[`${childKeyName}`]);
         }else{
              result.push(child);
         }
      }
    }
  }
  looper(treeData);
  return result
}






/*
 * @param x {Object} 对象1
 * @param y {Object} 对象2
 * @return  {Boolean} true 为相等，false 为不等
 */
export const deepEqual = (x: { [x: string]: any; } | null, y: { [x: string]: any; hasOwnProperty?: any; } | null) => {
  // 指向同一内存时
  if (x === y) {
    return true;
  } else if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
    if (Object.keys(x).length !== Object.keys(y).length) {
      return false;
    }
    for (var prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!deepEqual(x[prop], y[prop])) return false;
      } else {
        return false;
      }
    }
    return true;
  } else {
    return false;
  }
}


// 查找父节点的函数

interface Node {
  code: string;
  parentCode: number;
  [key: string]: any;
  children?: Node[];
}

export const findAllParents = (data: Node[], parentCode: string,childKeyName:string): Node[] => {
  let result: Node[] = [];

  function findNodeRecursively(node: Node, path: Node[]): boolean {
    if (node.code === `${parentCode}`) {
      result = [...path, node];
      return true;
    }

    if (node[`${childKeyName}`]&&node[`${childKeyName}`].length>0) {
      for (const child of node[`${childKeyName}`]) {
        if (findNodeRecursively(child, [...path, node])) {
          return true;
        }
      }
    }

    return false;
  }

  for (const node of data) {
    if (parentCode != '0' && findNodeRecursively(node, [])) {
      break;
    }
  }

  return result;
}


//获取所有children节点的code

interface TreeNode {
  code: string;
  [key: string]: any,
  children?: TreeNode[];
}


export const getNodesWithChildren = (tree: TreeNode[]): TreeNode[] => {
  let nodes: TreeNode[] = [];

  function helper(node: TreeNode) {
    if (node.children && node.children.length > 0) {
      // 当前节点包含 children，添加整个节点
      nodes.push(node);
      // 递归处理子节点
      for (const child of node.children) {
        helper(child);
      }
    }
  }

  // 在这个版本中，我们对每个根节点进行操作
  for (const node of tree) {
    helper(node);
  }

  return nodes;
}




//找出所有父节点的code



export const findParentCodes = (node: TreeNode, parentCodes: string[] = []): string[] => {
  if (node.children && node.children.length > 0) {
    parentCodes.push(node.code);

    for (let child of node.children) {
      findParentCodes(child, parentCodes);
    }
  }

  return parentCodes;
}


//更改树结构集合的子集属性名

export const renameChildListToChildren = (nodes: any[],key:string) => {
  return nodes.map(node => {
      // 创建当前节点的副本
      const newNode = { ...node };

      // 如果当前节点有 childList，则重命名为 children，并递归处理子节点
      if (newNode[`${key}`]&&newNode[`${key}`].length>0) {
          newNode.children = renameChildListToChildren(newNode[`${key}`],key);
      }

      return newNode;
  });
}


export const cleanTree = (nodes: TreeNode[]): TreeNode[] => {
  return nodes.map(node => {
    if (node.children) {
      if (node.children.length === 0) {
        const { children, ...rest } = node;
        return rest;
      } else {
        return { ...node, children: cleanTree(node.children) };
      }
    }
    return node;
  });
};



//将动态表头转换

type JsonStructure = {
  code: string;
  name: string;
  expand?: number;
  childTitle?: JsonStructure[];
};

type Column = {
  title: string;
  dataIndex: string;
  key: string;
  children?: Column[];
};

export const convertToColumns = (json: JsonStructure[]): Column[] => {
  return json.map((item) => {
    let column: Column = {
      title: item.name,
      dataIndex: item.code,
      key: item.code,
    };

    if (item.expand === 1 && item.childTitle && item.childTitle.length > 0) {
      column.children = convertToColumns(item.childTitle);
    }

    return column;
  });
}


//搜索树结构中叶子节点的某一个属性，并返回所有匹配的集合

export const searchLeaves = (nodes: any[], keywords: string | undefined, keyName: string, childrenKey: string, results: any[] = []): any[] => {
  for (const node of nodes) {
    if (!Array.isArray(node[childrenKey])) {
      if (node[keyName].indexOf(keywords) != -1) {
        results.push(node);
      }
    } else if (Array.isArray(node[childrenKey])) {
      searchLeaves(node[childrenKey], keywords, keyName, childrenKey, results);
    }
  }
  return results;
}


//导入按钮的下载模板

export const downloadTemplateReq = (pathStr: string) => {


  let path = `/gateway${pathStr}`;

  const userData = localStorage.getItem('userData');
  const { token = '' } = JSON.parse(userData as string);

  axios({
    method: 'get',
    url: path,
    responseType: 'blob',
    headers: { token },
  })
    .then(function (response) {
      //console.log({ 'chunk': response });
      const filename = decodeURI(response.headers["content-disposition"]);
      const objectUrl = URL.createObjectURL(
        new Blob([response.data], {
          type: 'application/vnd.ms-excel',
        })
      )
      const link = document.createElement('a')
      // 设置导出的文件名称
      link.download = `${filename}` + '.xls'
      link.style.display = 'none'
      link.href = objectUrl
      link.click()
      document.body.appendChild(link)

    });



}





//计算字符串长度px

export const getStringWidth = (str: string, font: string) => {
  // 创建一个临时元素
  var tempDiv = document.createElement('div');
  tempDiv.style.position = 'absolute';
  tempDiv.style.visibility = 'hidden';
  tempDiv.style.height = 'auto';
  tempDiv.style.width = 'auto';
  tempDiv.style.whiteSpace = 'nowrap';
  tempDiv.style.font = font; // 设置字体样式，例如 "12px Arial"
  tempDiv.textContent = str;

  // 将元素添加到文档中，以便进行测量
  document.body.appendChild(tempDiv);

  // 获取元素的宽度
  var width = tempDiv.clientWidth;

  // 移除临时元素
  document.body.removeChild(tempDiv);

  return width;
}



export const  copyToClipboard = (text:string) => {
  // 创建一个textarea元素
  const textarea = document.createElement('textarea');
  textarea.value = text;
  
  // 防止元素显示在视口中
  textarea.style.position = 'fixed';
  textarea.style.left = '-9999px';
  
  document.body.appendChild(textarea);
  
  // 选中文本
  textarea.select();
  textarea.setSelectionRange(0, 99999); // 对于移动设备

  try {
    // 执行复制命令
    const successful = document.execCommand('copy');
    if (successful) {
      console.log('Text copied to clipboard');
    } else {
      console.error('Failed to copy text');
    }
  } catch (err) {
    console.error('Error during copy to clipboard', err);
  }

  // 移除textarea元素
  document.body.removeChild(textarea);
}


/**
 * 根据输入日期和延期天数，返回延期后的日期
 * @param dateStr - 输入日期，格式为 yyyy-mm-dd
 * @param days - 延期的天数
 * @returns - 延期后的日期，格式为 yyyy-mm-dd
 */
export function calculateDelayedDate(dateStr: string, days: number): string {
  console.log({dateStr,days});
  // 将输入日期转换为 Date 对象
  const inputDate = new Date(dateStr);

  // 检查输入日期是否有效
  if (isNaN(inputDate.getTime())) {
      throw new Error("无效的日期格式，请使用 yyyy-mm-dd 格式");
  }

  // 延期天数的计算
  inputDate.setDate(inputDate.getDate() + days);

  // 格式化输出为 yyyy-mm-dd
  const year = inputDate.getFullYear();
  const month = String(inputDate.getMonth() + 1).padStart(2, "0"); // 月份从 0 开始
  const day = String(inputDate.getDate()).padStart(2, "0");

  return `${year}-${month}-${day}`;
}



export const getUrlParams = (url: string): { [key: string]: string | string[] } => {
  // 创建一个URL对象（假设URL是有效的）
  const urlObj = new URL(url);
  // 获取所有查询字符串
  const queryParams = new URLSearchParams(urlObj.search);
  const params: { [key: string]: string | string[] } = {};  // 定义具有索引签名的对象

  // 遍历查询字符串并将它们添加到params对象中
  for (const [key, value] of queryParams) {
      // 检查对象中是否已经存在这个键
      if (params.hasOwnProperty(key)) {
          // 如果这个键已经有值，将它转换为数组（如果尚未转换的话）
          if (!Array.isArray(params[key])) {
              params[key] = [params[key] as string];  // 作为 string 断言是安全的
          }
          // 添加新的值到数组
          (params[key] as string[]).push(value);
      } else {
          // 如果这个键还没有值，直接添加
          params[key] = value;
      }
  }

  return params;
}







