import { pinyin } from "pinyin-pro";
import { isArray } from "./is/index";
import { get } from "lodash-es";

/**
 * @description 判断字符串str是否包含目标字符串tgStr的拼音形式。
 * @param str 待检查的字符串
 * @param tgStr 目标字符串，用于拼音匹配
 * @returns 如果str的拼音形式包含tgStr，则返回true；否则返回false。
 */
const getMatch = (str: string, tgStr: string): boolean => {
  const result = pinyin(str, { toneType: "none", type: "array" });

  // 将拼音数组连接成字符串，用于完整拼音匹配
  let res = result.join("");
  if (res.includes(tgStr)) return true;

  // 将拼音数组的每个元素的首字母提取出来，然后连接成字符串，用于首字母拼音匹配
  res = result
    .map(p => p[0])
    .join("")
    .toLowerCase();
  return res.includes(tgStr);
};

/**
 * @description 拼音模糊查询数值
 * @param inputValue {string} 识别文本内容
 * @param totalList {array} 数据源，单层数组
 * @param props {array/string} 识别文本字段名
 * @returns array
 */
export function pinyinFilter(inputValue: string, totalList: any, props: string | string[]) {
  // 完整拼音
  const pyInput = pinyin(inputValue, { toneType: "none", type: "array" }).join("");

  // Helper函数来检查节点是否匹配
  function isNodeMatch(node: any, prop: string): boolean {
    const value = String(get(node, prop, ""));
    return value.includes(inputValue) || getMatch(value, pyInput);
  }

  return totalList.filter((e: any) => {
    let ifMatch = false;
    if (isArray(props)) {
      for (let i = 0; i < props.length; i++) {
        if (isNodeMatch(e, props[i])) {
          ifMatch = true;
          break;
        }
      }
    } else {
      ifMatch = isNodeMatch(e, props);
    }
    return ifMatch;
  });
}

/**
 * @description 拼音模糊查询数值
 * @param inputValue {string} 识别文本内容
 * @param totalList {array} 数据源，支持多层数组
 * @param props {array/string} 识别文本字段名，支持“a.b"
 * @param childAttr {string} 子层级字段名, 默认为children
 * @returns array
 */
export function pinyinFilterTree(inputValue: string, totalList: any, props: string | string[], childAttr: string = "children") {
  // 完整拼音
  const pyInput = pinyin(inputValue, { toneType: "none", type: "array" }).join("");

  // Helper函数来检查节点是否匹配
  function isNodeMatch(node: any, prop: string): boolean {
    const value = get(node, prop, "") as string;
    return value.includes(inputValue) || getMatch(value, pyInput);
  }

  return totalList
    .map((e: any) => {
      let ifMatch = false;
      if (isArray(props)) {
        for (let i = 0; i < props.length; i++) {
          if (isNodeMatch(e, props[i])) {
            ifMatch = true;
            break;
          }
        }
      } else {
        ifMatch = isNodeMatch(e, props);
      }

      if (ifMatch) return e;

      // 如果当前节点不匹配，但存在子节点，则递归处理子节点
      if (e.hasOwnProperty(childAttr) && e[childAttr].length > 0) {
        const filteredChildren = pinyinFilterTree(inputValue, e[childAttr], props, childAttr);
        if (filteredChildren.length > 0) {
          let _data = { ...e };
          _data[childAttr] = filteredChildren;
          return _data;
        }
      }
      return null;
    })
    .filter((node: any) => node !== null); // 过滤掉 null 节点
}
