import dayjs from 'dayjs';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
import _, { cloneDeep, find } from 'lodash';
import { columnsTiltle } from '../utils/const';
import token from './token';

export { formatUserRender } from './jsxformat';

dayjs.extend(quarterOfYear);

export const formatPostData = <
  T extends { children?: T[] },
  W extends { children?: W[]; parentNode?: T },
>(
  data: T[],
  fuc: (item: T) => W,
  parentNode?: T,
  isparent: boolean = true,
): W[] => {
  return data?.map((item: T): W => {
    const formattedNode = fuc({ ...item, parentNode: isparent ? parentNode : undefined });
    if (item?.children && item?.children?.length > 0) {
      // @ts-ignore
      formattedNode.children = formatPostData(item.children, fuc, formattedNode, isparent);
    }
    return formattedNode;
  });
};
// 数据扁平化
const dealTreeData = (data: any) => {
  const arrTree: any = [];
  data.forEach((ele: any) => {
    arrTree.push(ele);
    if (ele?.children?.length) {
      arrTree.push(...dealTreeData(ele.children));
    }
  });
  return arrTree;
};

export const findFromTree = (tree, fn) => {
  return find(dealTreeData(tree), fn);
};

export const getDeepKey = (key?: string) => {
  const extractIds = (node) => {
    if (Array.isArray(node)) {
      return _.flatMapDeep(node, extractIds);
    } else if (node && typeof node === 'object') {
      let n = node;
      if (key) {
        n = node[key];
      }
      return [n].concat(extractIds(node.children || []));
    } else {
      return [];
    }
  };
  return extractIds;
};

export const validate = (isHaveDate, tempSelectIdMap, onChange) => {
  const selectIdMapKeys = Object.keys(tempSelectIdMap);
  const selectIdMapValues = Object.values(tempSelectIdMap);
  if (!isHaveDate) {
    onChange({ data: selectIdMapValues });
    return;
  }
  const isValidate =
    selectIdMapKeys.length ===
    selectIdMapValues.filter((selectId: any) => {
      return selectId.expiredAt || selectId.expiredAt === 0;
    }).length;

  if (!isValidate) {
    onChange?.({ error: { error: true, message: '请选择有效日期' }, data: selectIdMapValues });
  } else {
    onChange?.({ data: selectIdMapValues });
  }
};

export const validateDay = (isHaveDay, tempSelectIdMap, onChange) => {
  const selectIdMapKeys = Object.keys(tempSelectIdMap);
  const selectIdMapValues = Object.values(tempSelectIdMap);
  if (!isHaveDay) {
    onChange({ data: selectIdMapValues });
    return;
  }
  const isValidate =
    selectIdMapKeys.length ===
    selectIdMapValues.filter((selectId: any) => {
      return selectId.expiredAt || selectId.expiredAt === 0;
    }).length;

  if (!isValidate) {
    onChange?.({ error: { error: true, message: '请选择有效期' }, data: selectIdMapValues });
  } else {
    onChange?.({ data: selectIdMapValues });
  }
};
export const formatUser = (user, formatMessage) =>
  user
    ? `${user.nameZh || user.cnName || user.name}${
        user.account || user.userName ? `（${user.account || user.userName}）` : ''
      }${user?.state === 0 ? formatMessage({ id: 'base.common.user.state.dimission' }) : ''}`
    : '';
export const formatNameLable = (data) => {
  return data.map((item) => {
    const title = item.name;
    if (item.children && item.children.length > 0) {
      return {
        title,
        value: item.id,
        children: formatNameLable(item.children),
      };
    }
    return {
      title,
      value: item.id,
    };
  });
};
export const formatTreeLable = (data) => {
  return data.map((item) => {
    const label = `${item.name} - (${item.uniqueKey})`;
    // `${parentLabel}${parentLabel ? ' - ' : ''}
    if (item.children && item.children.length > 0) {
      return {
        label,
        flagId: item?.flagId || null,
        value: item.uniqueKey,
        children: formatTreeLable(item.children),
      };
    }
    return {
      label,
      value: item.uniqueKey,
      flagId: item?.flagId || null,
    };
  });
};
export const formatFlagTreeLable = (data) => {
  return data.map((item) => {
    const label = `${item.name} - (${item.uniqueKey})`;
    // `${parentLabel}${parentLabel ? ' - ' : ''}
    if (item.children && item.children.length > 0) {
      return {
        label,
        // 存在flagid 为属性 不存在则 为 flag
        value: JSON.stringify({
          flagId: item?.flagId ? item?.flagId : '',
          uniqueKey: item.uniqueKey,
        }),
        // 存在flagUniqueKey为 flag "flag" 否则"flag:uni"
        children: formatFlagTreeLable(item.children),
      };
    }
    return {
      label,
      value: JSON.stringify({
        flagId: item?.flagId ? item?.flagId : '',
        uniqueKey: item.uniqueKey,
      }),
    };
  });
};
export const formatTreeLableUnikey = (data) => {
  return data.map((item) => {
    const name = `${item.name} - (${item.uniqueKey})`;
    // `${parentLabel}${parentLabel ? ' - ' : ''}
    if (item.children && item.children.length > 0) {
      return {
        name,
        id: String(item.id),
        children: formatTreeLableUnikey(item.children),
      };
    }
    return {
      name,
      id: String(item.id),
    };
  });
};

// 过滤tree数据结构
export const filterTree = (array, func) => {
  const getNodes = (result, object) => {
    if (func(object)) {
      result.push(object);
      return result;
    }
    if (Array.isArray(object.children)) {
      const children = object.children.reduce(getNodes, []);
      if (children.length) result.push({ ...object, children });
    }
    return result;
  };

  return array?.reduce?.(getNodes, []);
};
export const formatTimeDate = (timestamp) => {
  const time = new Date(timestamp * 1000);
  const year = time.getFullYear();
  const month = time.getMonth() + 1;
  const date = time.getDate();
  return year + '-' + month + '-' + date;
};
export const formatTimeDateSeconds = (timestamp) => {
  const time = new Date(timestamp * 1000);
  const year = time.getFullYear();
  const month = time.getMonth() + 1;
  const date = time.getDate();
  const hours = time.getHours();
  const minutes = time.getMinutes();
  const seconds = time.getSeconds();
  return year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + seconds;
};

export function traverseAndAddAttribute(node: any) {
  node?.map((item: any) => {
    if (item?.optionTree) {
      item.children = item.optionTree;
    }
    if (!item.hasOwnProperty('optionTree')) {
      item.name = item.name;
    }
    if (item?.children) {
      traverseAndAddAttribute(item?.children);
    }
  });
}

export const formatTreeList = (list) => {
  const arrColumns: any = [];
  list?.map((item) => {
    let arr: any[] = [];
    // 遍历数组中的属性给属性添加typeName
    const { city, feature, option, policy, role } = item;
    const obj = { city, feature, option, policy, role };
    for (const key in obj) {
      traverseAndAddAttribute(obj[key]);
    }
    const optionMap: any[] = [];
    option.map((opt) => {
      optionMap.push(...opt.children);
    });
    arr = [...city, ...feature, ...optionMap, ...policy, ...role];
    arrColumns.push(...arr);
  });
  return arrColumns;
};
export const uniqueObjectsById = (array, key) => {
  const seen = new Set();
  return array.filter((item) => {
    const k = item[key];
    return seen.has(k) ? false : seen.add(k);
  });
};
export const generateColumns = (key, columns) => {
  const temp = cloneDeep(columns);
  temp?.map((item) => {
    if (item.hasOwnProperty('hideInTable')) {
      if (columnsTiltle[key].id === item.title.props.id) {
        item.hideInTable = false;
      } else {
        item.hideInTable = true;
      }
    }
  });
  return temp;
};
export const chunkArray = (array, rows) => {
  if (!Array.isArray(array)) {
    return;
  }
  const multiDimArray = Array(rows).fill([]);
  let j = 0;
  const last = array?.length % rows;
  const len = parseInt(String(array?.length / rows));
  if (array.length >= rows) {
    for (let i = 0; i < rows; i++) {
      // 将数组分割成4分 array/4 剩下的放到最后一个数组中
      multiDimArray[i] = array.slice(j, len * (i + 1));
      j = len + j;
      if (i == rows - 1 && last > 0) {
        // 最后一个长度了
        const lastList = array.slice(-last);
        for (let l = 0; l < lastList.length; l++) {
          multiDimArray[l].push(lastList[l]);
        }
      }
    }
  } else {
    for (let i = 0; i < array.length; i++) {
      multiDimArray[i] = [array[i]];
    }
  }
  return multiDimArray;
};
export function getAllIds(tree) {
  if (!tree?.length) {
    return;
  }
  const ids: any[] = [];
  function traverse(node) {
    if (node && node.id) {
      // 假设每个节点都有一个id属性
      ids.push(node.id);
    }
    if (node && node.children) {
      // 假设每个节点都有一个children属性，它是一个数组
      for (const child of node.children) {
        traverse(child); // 递归遍历子节点
      }
    }
  }

  for (const node of tree) {
    traverse(node); // 遍历树的根节点
  }

  return ids;
}
export function extractStrings(str) {
  const regex = /^(.*?)(\(.*?\))(.*)$/;
  const match = str.match(regex);
  let outside = '';
  let inside = '';
  let after = '';
  if (match) {
    // match[1] 是括号外的部分
    // match[2] 是包括括号的部分，我们需要进一步处理来去掉括号
    // match[3] 是括号后面的部分
    outside = match[1].trim(); // 去掉可能的前后空格
    inside = match[2].replace(/^\(|\)$/g, ''); // 去掉括号
    after = match[3].trim(); // 去掉可能的前后空格
    return { outside, inside, after: after === '已离职' ? 0 : 1 };
  } else {
    // 如果没有匹配到，返回一个空对象或适当的错误处理
    return {};
  }
}
type Preset<T> = {
  label: string;
  value: T | (() => T);
};

type DateTimeRangeProps<T> = {
  presets: Preset<T>[];
};
export const dateTimeRangeProps = (
  formatMessage,
): DateTimeRangeProps<[dayjs.Dayjs, dayjs.Dayjs]> => {
  return {
    presets: [
      {
        label: formatMessage({ id: 'base.event.10' }),
        value: () => [dayjs().add(-10, 'm'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.30' }),
        value: () => [dayjs().add(-30, 'm'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.60' }),
        value: () => [dayjs().add(-60, 'm'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.12' }),
        value: () => [dayjs().add(-12, 'h'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.24' }),
        value: () => [dayjs().add(-24, 'h'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.7' }),
        value: () => [dayjs().add(-7, 'd'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.14' }),
        value: () => [dayjs().add(-14, 'd'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.30day' }),
        value: () => [dayjs().add(-30, 'd'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.90' }),
        value: () => [dayjs().add(-90, 'd'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.180' }),
        value: () => [dayjs().add(-180, 'd'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.365' }),
        value: () => [dayjs().add(-365, 'd'), dayjs()],
      },

      {
        label: formatMessage({ id: 'base.event.today' }),
        value: () => [dayjs().startOf('d'), dayjs().endOf('day')],
      },
      {
        label: formatMessage({ id: 'base.event.yes' }),
        value: () => [dayjs().add(-1, 'd').startOf('d'), dayjs().add(-1, 'd').endOf('d')],
      },
      {
        label: formatMessage({ id: 'base.event.week' }),
        value: () => [dayjs().startOf('w'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.last.week' }),
        value: () => [dayjs().add(-1, 'w').startOf('w'), dayjs().add(-1, 'w').endOf('w')],
      },
      {
        label: formatMessage({ id: 'base.event.month' }),
        value: () => [dayjs().startOf('M'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.last.month' }),
        value: () => [dayjs().add(-1, 'M').startOf('M'), dayjs()],
      },
      {
        label: formatMessage({ id: 'base.event.quarter' }),
        value: () => [
          dayjs().quarter(dayjs().quarter()).startOf('quarter'),
          dayjs().quarter(dayjs().quarter()).endOf('quarter'),
        ],
      },
      {
        label: formatMessage({ id: 'base.event.last.quarter' }),
        value: () => [
          dayjs()
            .quarter(dayjs().quarter() - 1)
            .startOf('quarter'),
          dayjs()
            .quarter(dayjs().quarter() - 1)
            .endOf('quarter'),
        ],
      },
    ],
  };
};
export const dateTimeProps = (formatMessage): DateTimeRangeProps<dayjs.Dayjs> => {
  return {
    presets: [
      {
        label: formatMessage({ id: 'base.event.10' }),
        value: () => dayjs().add(-10, 'm'),
      },
      {
        label: formatMessage({ id: 'base.event.30' }),
        value: () => dayjs().add(-30, 'm'),
      },
      {
        label: formatMessage({ id: 'base.event.60' }),
        value: () => dayjs().add(-60, 'm'),
      },
      {
        label: formatMessage({ id: 'base.event.12' }),
        value: () => dayjs().add(-12, 'h'),
      },
      {
        label: formatMessage({ id: 'base.event.24' }),
        value: () => dayjs().add(-24, 'h'),
      },
      {
        label: formatMessage({ id: 'base.event.7' }),
        value: () => dayjs().add(-7, 'd'),
      },
      {
        label: formatMessage({ id: 'base.event.14' }),
        value: () => dayjs().add(-14, 'd'),
      },
      {
        label: formatMessage({ id: 'base.event.30day' }),
        value: () => dayjs().add(-30, 'd'),
      },
      {
        label: formatMessage({ id: 'base.event.90' }),
        value: () => dayjs().add(-90, 'd'),
      },
      {
        label: formatMessage({ id: 'base.event.180' }),
        value: () => dayjs().add(-180, 'd'),
      },
      {
        label: formatMessage({ id: 'base.event.365' }),
        value: () => dayjs().add(-365, 'd'),
      },

      {
        label: formatMessage({ id: 'base.event.today' }),
        value: () => dayjs().startOf('d'),
      },
      {
        label: formatMessage({ id: 'base.event.yes' }),
        value: () => dayjs().add(-1, 'd').startOf('d'),
      },
      {
        label: formatMessage({ id: 'base.event.week' }),
        value: () => dayjs().startOf('w'),
      },
      {
        label: formatMessage({ id: 'base.event.last.week' }),
        value: () => dayjs().add(-1, 'w').startOf('w'),
      },
      {
        label: formatMessage({ id: 'base.event.month' }),
        value: () => dayjs().startOf('M'),
      },
      {
        label: formatMessage({ id: 'base.event.last.month' }),
        value: () => dayjs().add(-1, 'M').startOf('M'),
      },
      {
        label: formatMessage({ id: 'base.event.quarter' }),
        value: () => dayjs().quarter(dayjs().quarter()).startOf('quarter'),
      },
      {
        label: formatMessage({ id: 'base.event.last.quarter' }),
        value: () =>
          dayjs()
            .quarter(dayjs().quarter() - 1)
            .startOf('quarter'),
      },
    ],
  };
};

export const filterTreeByIds = (tree, ids) => {
  const idSet = new Set(ids);

  function filter(node) {
    if (!node) return null;

    // 如果当前节点是叶子节点且不在idSet中，则不包括它
    if (!node.children || node.children.length === 0) {
      return idSet.has(node.id) ? { ...node } : null;
    }

    // 递归过滤children
    const children = (node.children || []).map((child) => filter(child)).filter((n) => n !== null);

    // 如果当前节点的id在idSet中或有非空的children，则包括当前节点
    if (idSet.has(node.id) || children.length > 0) {
      return {
        ...node,
        children: children,
      };
    }

    return null;
  }

  // 对树的根节点应用filter函数
  const filteredTree = tree.map((rootNode) => filter(rootNode)).filter((n) => n !== null);

  return filteredTree;
};

export default {
  ...token,
  formatPostData,
  getDeepKey,
  validate,
  formatUser,
  formatTreeLable,
  filterTree,
  formatNameLable,
  formatFlagTreeLable,
  formatTreeLableUnikey,
  formatTimeDate,
  formatTreeList,
  traverseAndAddAttribute,
  uniqueObjectsById,
  generateColumns,
  formatTimeDateSeconds,
  chunkArray,
  getAllIds,
  extractStrings,
  dateTimeRangeProps,
  dateTimeProps,
  filterTreeByIds,
};
