// import VisualEngine from '@ali/visualengine';
import {
  _dataSourceName,
  allowSelectFirstComponentList,
  dataOriginRequest,
  dataOriginStatic,
  formUrlencoded,
  needSaveDataFlowActionList, pageDataSource,
  preMokelayDomain,
  recursionComponentList,
} from './const';
import { DisplayPosition } from '../manager/position/display-position';
import isNaN from 'lodash/isNaN';
import isNumber from 'lodash/isNumber';
import trim from 'lodash/trim';
import { ButtonPosition } from '../manager/position/button-position';
import { ValidatorPosition } from '../manager/position/validator-position';
import isPlainObject from 'lodash/isPlainObject';
import isArray from 'lodash/isArray';
import merge from 'lodash/merge';
import get from 'lodash/get';
import { customAlphabet } from 'nanoid';
import { CnButton, CnIcon, CnMessage, CnBalloon } from '@cainiaofe/cn-ui';
import {
  getRealResponse,
  handleRequestParams,
  makeRequest,
  transRequestConfigToRemote,
} from './request';
import {
  componentMap as filterItemComponentMap,
  transRulesToValidator,
  getRunTimeItem as getFilterRunTimeItem,
} from '../manager/filter-item';
import {
  getButtonAction,
  getItem as getButtonItem,
} from '@/common/manager/button';
import React from 'react';
import { getExtComponent } from '@alife/cn-lowcode-utils';
import uniq from 'lodash/uniq';
import dayjs from 'dayjs';
import cloneDeep from 'lodash/cloneDeep';
import {
  __arrayTableCurrentRow__,
  __dataSource__,
  __extraParam__,
  __filterValue__,
  __formValue__,
  __left_tree_currentItem__,
  __left_tree_currentValue__,
  __paging__,
  __selectedRowKeys__,
  __selectedRowRecords__,
  __stateValueOfSplit__,
  __tab_activeKey__,
  __tableColumns__,
  __tableCurrentRow__,
  __tableData__,
  __tableExtra__,
  __permissionGranted__,
  formDialogStateLabel,
  openDialogModeLabel,
  symbolMap,
  tableCurrentRowLabel,
  arrayTableCurrentRowLabel,
  arrayTableCurrentRowIndex,
  tableCurrentRowByOperateClickLabel,
  tableCurrentRowIndexByOperateClickLabel,
  iceStore,
  button_view,
  __statisticCard_activeKey__,
  __list_activeKey__,
  tableCurrentRowIndex,
  __arrayTableCurrentRowIndex__,
  __arrayTableCurrentRowByWhole__,
  __arrayTableCurrentRowIndexByWhole__,
  arrayCardCurrentRowLabel,
  arrayCardCurrentRowIndex,
  __arrayCardCurrentRowByWhole__,
  __arrayCardCurrentRowIndexByWhole__,
  __statisticCard_currentItem__,
  __list_currentItem__,
  __statisticCard_clickKey__,
  __statisticCard_clickItem__, currentPageLabel, pageSizeLabel, sortListLabel,
} from '@/common/util/expr-const';
import qs from 'query-string';
import $i18n from 'panda-i18n';
import {
  _getContext,
  _getFormValues,
} from '@/common/util/biz-component-prop-name';
import { CnButtonProxy } from '@/common/manager/filter-item/components/cn-button-proxy';
import isString from 'lodash/isString';

const { VisualEngine } = window;
const Engine = VisualEngine;

// 缓存表单配置项
const cacheFormConfig = {};
const FIELD_NAME = 'fieldName';
// 表单字段编码
const NAME = 'name';
const ID_NAME = 'id';
// CnFilter.Item的props，切换组件类型时这些属性将保留
const FIELD_ITEM_FIXED_PROPS = [
  'label',
  NAME,
  'componentName',
  'span',
  'hidden',
  'placeholder',
  'hasClear',
];
export const __urlParams__ = '__urlParams__';
export const __record__ = '__record__';
export const __index__ = '__index__';
export const __state__ = '__state__';
export const __ds__ = '__ds__';
export const __blank__ = '__blank__';
const messageTypeMap = {
  success: 'success',
  warning: 'warning',
  error: 'error',
  notice: 'notice',
  help: 'help',
  loading: 'loading',
};

function visibleRun(extraProps, visible, type, run) {
  const { requestConfig, state, recordDataSource } = extraProps || {};
  const execute = calculateRequestExecute(
    requestConfig,
    {
      [__formValue__]: recordDataSource,
      [__filterValue__]: recordDataSource,
      [__dataSource__]: state,
    },
    recordDataSource || {},
    state,
  );
  if (visible && execute !== false) {
    run?.();
  }
}

/**
 * 所有获取 id 的地方都应该通过 getId
 * @param {object} field
 */
const getId = (field) => {
  if (field.getPropValue || field.props) {
    return getNodeProp(field, ID_NAME);
  }
  return field[ID_NAME];
};

const generateIndex = (dataSourceList, componentName, key = 'value') => {
  let index = 2;
  while (
    dataSourceList.find((item) => item[key] === `${componentName}${index}`)
  ) {
    index++;
  }
  return index;
};

const getDataSourceList = (config) => {
  const { typeList, needChildren } = config || {};
  const dataSource = VisualEngine?.context?.getManager('dataPool');
  const items = dataSource?.getItems();
  const result = [];
  if (items?.length > 0) {
    items.forEach((item) => {
      const { id, name, type, config: dsConfig } = item;
      const label = dsConfig?.description || name;
      const ds = {
        text: label,
        label,
        value: name,
        dataSourceId: dsConfig?.id,
        id,
      };
      const temp = findNodeConfigListByDataSourceName({
        dsNameKey: '_dataSourceName',
        dsName: name,
      });
      const { configList, node } = temp || {};
      const title = getNodeTitle(node);
      ds.componentName = node?.componentName;
      if (title) {
        ds.label = title;
        ds.text = title;
      }
      if (needChildren) {
        if (configList?.length > 0) {
          ds.children = configList;
        }
      }
      if (Array.isArray(typeList) && typeList.length > 0) {
        if (typeList.includes(type)) {
          result.push(ds);
        }
      } else {
        result.push(ds);
      }
    });
  }
  return result;
};
const getDataSourceListWithAllPath = (config) => {
  const { typeList, needChildren, prototypeConfig } = config || {};
  const dataSource = VisualEngine?.context?.getManager('dataPool');
  const items = dataSource?.getItems();
  const result = [];
  const { flowList, currentFlowIndex } = prototypeConfig || {};
  if (items?.length > 0) {
    items.forEach((item) => {
      const { name, type, config: dsConfig } = item;
      const label = dsConfig?.description || name;
      const ds = {
        text: label,
        label,
        value: `state.${name}`,
      };
      const temp = findNodeConfigListByDataSourceName({
        dsNameKey: '_dataSourceName',
        dsName: name,
      });
      const { configList, node } = temp || {};
      const title = getNodeTitle(node);
      if (title) {
        ds.label = title;
        ds.text = title;
      }
      if (needChildren) {
        if (configList?.length > 0) {
          ds.children = configList;
        }
      }
      if (Array.isArray(typeList) && typeList.length > 0) {
        if (typeList.includes(type)) {
          result.push(ds);
        }
      } else {
        result.push(ds);
      }
    });
  }

  if (
    typeof currentFlowIndex === 'number' &&
    Array.isArray(flowList) &&
    flowList.length > 0
  ) {
    const existFlowList = flowList.slice(0, currentFlowIndex);
    if (existFlowList?.length > 0) {
      const extra = {
        label: '动作编排的数据',
        children: createSelectList(existFlowList),
      };

      if (extra.children.length > 0) {
        result.unshift(extra);
      }
    }
  }
  return result;
};
function createSelectList(list, valuePrePath = 'state') {
  const retList = []
  list?.forEach?.((item, index) => {
    const { optType, active, options, prefix } = item || {};
    if (optType && active !== false) {
      if (needSaveDataFlowActionList.includes(optType)) {
        let realIndex = index;
        if(isNumber(prefix?.changeIndex)) {
          realIndex += prefix?.changeIndex;
        }
        if (realIndex === 0) {
          realIndex = '';
        }
        let realPath = optType;
        if(prefix?.path) {
          realPath = `${prefix?.path}_${realPath}`;
        }
        const currentFlowValue = `${valuePrePath}.valueOf.${realPath}${realIndex}`;
        let realLabel = '发请求';
        if (optType === 'submit') {
          realLabel = '提交';
        } else if (optType === 'pollingAction') {
          // realLabel = '轮询操作';
          const childrenList = options?.pollingItem?.map?.(citem=> {
            if(isPlainObject(citem)) {
              citem.prefix = {
                path: `polling${index}`,
                text: `轮询${realIndex}`
              }
            }
            return citem;
          })
          const childrenRet = createSelectList(childrenList ?? [], valuePrePath);
          retList.push(...childrenRet);
          return;
        }
        if(isString(prefix?.text)) {
          realLabel = `${prefix?.text}的${realLabel}`;
        }

        retList.push({
          label: `${realLabel}${realIndex}`,
          value: currentFlowValue,
          children: [
            {
              label: 'success',
              value: `${currentFlowValue}.success`,
            },
            {
              label: 'data',
              value: `${currentFlowValue}.data`,
            },
            {
              label: 'msg',
              value: `${currentFlowValue}.msg`,
            },
          ],
        });

      }
    }
  });
  return retList;
}

function getDataSourceByName(name) {
  return VisualEngine?.context?.getManager?.('dataPool')?.getItemByName?.(name);
}
function getDataSourceById(id) {
  return VisualEngine?.context?.getManager?.('dataPool')?.getItemById?.(id);
}

const findNodeConfigListByDataSourceName = (config) => {
  const { dsNameKey, dsName } = config || {};
  const nodesMap = VisualEngine?.designer?.currentDocument?.nodesMap;
  const result = {
    configList: [],
    node: null,
  };
  if (nodesMap?.values()) {
    for (const item of nodesMap?.values()) {
      if (item?.getPropValue?.(dsNameKey) === dsName) {
        const { componentName } = item;
        if (componentName === 'CnTable') {
          result.configList = [
            {
              label: tableCurrentRowLabel,
              text: tableCurrentRowLabel,
              value: `state.${dsName}.${__tableCurrentRow__}`,
            },
            {
              label: '选中数据主键列表(selectedRowKeys)',
              text: '选中数据主键列表(selectedRowKeys)',
              value: `state.${dsName}.${__selectedRowKeys__}`,
            },
            {
              label: '选中数据列表(selectedRowRecords)',
              text: '选中数据列表(selectedRowRecords)',
              value: `state.${dsName}.${__selectedRowRecords__}`,
            },
            {
              label: '表格请求返回的数据(tableData)',
              text: '表格请求返回的数据(tableData)',
              value: `state.${dsName}.${__tableData__}`,
            },
            {
              label: '表格的列头(columns)',
              text: '表格的列头(columns)',
              value: `state.${dsName}.${__tableColumns__}`,
            },
            {
              label: '表格请求返回的分页信息(paging)',
              text: '表格请求返回的分页信息(paging)',
              value: `state.${dsName}.${__paging__}`,
              children: [
                {
                  label: '当前页(currentPage)',
                  text: '当前页(currentPage)',
                  value: `state.${dsName}.${__paging__}.currentPage`,
                },
                {
                  label: '每页显示几条(pageSize)',
                  text: '每页显示几条(pageSize)',
                  value: `state.${dsName}.${__paging__}.pageSize`,
                },
                {
                  label: '数据总个数(totalCount)',
                  text: '数据总个数(totalCount)',
                  value: `state.${dsName}.${__paging__}.totalCount`,
                },
              ],
            },
            {
              label: '请求返回的额外信息(extra)',
              text: '请求返回的额外信息(extra)',
              value: `state.${dsName}.${__tableExtra__}`,
            },
          ];
        } else if (componentName === 'CnTab') {
          result.configList = [
            {
              label: 'Tab的选中项',
              text: 'Tab的选中项',
              value: `state.${dsName}.${__tab_activeKey__}`,
            },
          ];
        } else if (componentName === 'CnStatisticCard') {
          result.configList = [
            {
              label: '当前选中的指标卡(key)',
              text: '当前选中的指标卡(key)',
              value: `state.${dsName}.${__statisticCard_activeKey__}`,
            },
            {
              label: '当前选中的指标卡全部信息',
              text: '当前选中的指标卡全部信息',
              value: `state.${dsName}.${__statisticCard_currentItem__}`,
            },
            {
              label: '当前点击的指标卡(key)',
              text: '当前点击的指标卡(key)',
              value: `state.${dsName}.${__statisticCard_clickKey__}`,
            },
            {
              label: '当前点击的指标卡全部信息',
              text: '当前点击的指标卡全部信息',
              value: `state.${dsName}.${__statisticCard_clickItem__}`,
            },
          ];
        } else if (componentName === 'CnLeftTree') {
          result.configList = [
            {
              label: '当前点击的节点编码',
              text: '当前点击的节点编码',
              value: `state.${dsName}.${__left_tree_currentValue__}`,
            },
            {
              label: '当前选中的节点全部信息',
              text: '当前选中的节点全部信息',
              value: `state.${dsName}.${__left_tree_currentItem__}`,
            },
          ];
        } else if (componentName === 'CnList') {
          result.configList = [
            {
              label: '列表的选中项(key)',
              text: '列表的选中项(key)',
              value: `state.${dsName}.${__list_activeKey__}`,
            },
            {
              label: '列表的选中的全部信息',
              text: '列表的选中的全部信息',
              value: `state.${dsName}.${__list_currentItem__}`,
            },
          ];
        } else {
          const configList = item?.getPropValue?.('config');
          if (isArrayNotEmpty(configList)) {
            const tempList = handleOriginList(
              configList,
              'label',
              'name',
              `state.${dsName}`,
              { dsName, handleComposeComponent: true },
            );
            if (isArrayNotEmpty(tempList)) {
              result.configList = [...result.configList, ...tempList];
            }
          }
          if (componentName === 'CnFormDialog') {
            result.configList.push({
              label: formDialogStateLabel,
              children: [
                {
                  label: openDialogModeLabel,
                  value: `state.valueOf.${dsName}${__stateValueOfSplit__}openDialogMode`,
                },
              ],
            });
          }
        }
        result.node = item;
        break;
      }
    }
  }
  return result;
};

const transProxyToObject = (origin) => {
  const result = {};
  if (typeof origin === 'object') {
    const keys = Object.keys(origin);
    if (keys && keys.length > 0) {
      keys.forEach((key) => {
        result[key] = origin[key];
      });
    }
  }
  return result;
};

const getDsNameFromVariable = (dsExpr) => {
  let result = '';
  if (dsExpr && dsExpr.variable) {
    result = dsExpr.variable.slice(dsExpr.variable.lastIndexOf('.') + 1);
  }
  return result;
};

// 根据类型返回是否需要隐藏
function hidden(type, paramKey = 'componentName') {
  return function () {
    return this?.parent?.getParam(paramKey)?.toData?.() !== type;
  };
}
function condition(prop, type, primaryKey) {
  return prop?.parent?.parent?.getPropValue?.(primaryKey) === type;
}

// function isTextExprTrue(str, ...args) {
//   if (typeof str === 'boolean') {
//     return str;
//   } else if (typeof str === 'function') {
//     let result;
//     try {
//       const params = args.map((item) => {
//         if (item === null || item === undefined) {
//           return {};
//         }
//         return item;
//       });
//       result = str(...params);
//     } catch (e) {
//     }
//     if (typeof result === 'boolean') {
//       return result;
//     }
//   } else if (typeof str === 'string') {
//     const func = transTextExprToFunction(str);
//     const params = [...args];
//     let first = {};
//     let last = {};
//     let state = {}
//     if (params.length > 0) {
//       first = args[0] || {};
//       state = args[args.length - 1];
//       if (state && state.urlParams) {
//         last = state.urlParams;
//       }
//     }
//     const result = executeFunction(func, first, last, state || {});
//     if (typeof result === 'boolean') {
//       return result;
//     }
//   }
// }

// 执行对象表达式
function executeObjectExpr(str, objExprArgMap, ...args) {
  if (typeof str === 'boolean') {
    return str;
  } else if (typeof str === 'function') {
    let result;
    try {
      const params = args.map((item) => {
        if (item === null || item === undefined) {
          return {};
        }
        return item;
      });
      result = str(...params);
    } catch (e) {}
    if (typeof result === 'boolean') {
      return result;
    }
  } else if (typeof str === 'string' && str.length > 0) {
    const func = transTextExprToFunction(str);
    const params = [...args];
    let first = {};
    let last = {};
    let state = {};
    if (params.length > 0) {
      first = args[0] || {};
      state = args[args.length - 1];
      if (state && state.urlParams) {
        last = state.urlParams;
      }
    }
    const result = executeFunction(func, first, last, state || {});
    if (typeof result === 'boolean') {
      return result;
    }
  } else if (isPlainObject(str)) {
    const { group, param, secondParam, symbol, type, value, thirdParam } = str;
    if (group && param && symbol) {
      let leftValue;
      if (group === __dataSource__) {
        if (secondParam) {
          if (
            param === `valueOf.${__permissionGranted__}` &&
            window?.VisualEngine
          ) {
            // 编辑态不要生效  isDesign参数这里不好拿 用window?.VisualEngine 代替
            return false;
          }
          leftValue = get(
            objExprArgMap,
            `${group}.${param}.${secondParam}${
              thirdParam ? `.${thirdParam}` : ''
            }`,
          );
        }
      } else {
        leftValue = get(objExprArgMap, `${group}.${param}`);
      }
      const func = symbolMap[symbol];
      if (typeof func === 'function') {
        const result = func(leftValue, value, str);
        if (typeof result === 'boolean') {
          return result;
        }
      }
    }
  }
}

function isObjectExpr(obj) {
  if (isPlainObject(obj) && obj.group && obj.param && obj.symbol) {
    return true;
  }
  return false;
}

function isValueObjectExpr(obj) {
  return !!(isPlainObject(obj) && obj.group && obj.param);
}

function isDesignMode(props) {
  let mode;
  if (isPlainObject(props)) {
    mode = props?.__designMode;
  } else if (typeof props === 'string') {
    mode = props;
  }
  return mode === 'design';
}

// 获取业务组件列表
function getBizComponentNameList(position) {
  let result = [];
  if (VisualEngine) {
    const componentsMap = VisualEngine?.designer?.getComponentsMap?.();
    if (componentsMap) {
      result = Object.keys(componentsMap);
    }
    // VisualEngine?.designer?._componentMetasMap?.forEach((item) => {
    //   if (item?.prototype) {
    //     const { options } = item.prototype;
    //     if (options) {
    //       const { componentName, title, cnLowCodeConfig = {} } = options;
    //       if (cnLowCodeConfig[componentType]) {
    //         result.push({
    //           ...cnLowCodeConfig,
    //           title,
    //           componentName,
    //           component: {
    //             realize: () => {
    //               return VisualEngine.designer.componentsMap[componentName];
    //             },
    //           },
    //         });
    //       }
    //     }
    //   }
    // });
  }
  return result;
}

function getBizComponent(name, position) {
  if (name) {
    const componentMeta = VisualEngine?.designer?.getComponentMeta(name);
    if (componentMeta) {
      const { prototype } = componentMeta;
      if (prototype) {
        const config = prototype.getConfig?.();
        const packageName = prototype.getPackageName?.();
        if (config) {
          const runtimeComponent = getRunTimeBizComponent(name);
          const {
            title,
            category,
            cnLowCodeConfig,
            componentName,
            configure = [],
          } = config;
          if (cnLowCodeConfig && componentName && runtimeComponent) {
            const { position: comPosition = [] } = cnLowCodeConfig;
            if (comPosition.includes(position)) {
              const tempList = [
                DisplayPosition.filter,
                DisplayPosition.form,
                DisplayPosition.formDialog,
                DisplayPosition.tableCell,
                ButtonPosition.tableCell,
                ButtonPosition.tableOperate,
                ButtonPosition.tableBatchArea,
                ButtonPosition.tableToolArea,
                ButtonPosition.formDialog,
                ButtonPosition.form,
                ValidatorPosition.formDialog,
                ValidatorPosition.form,
                DisplayPosition.tableRowDetail,
                DisplayPosition.cnArrayTable,
                ButtonPosition.dialog,
                DisplayPosition.dialogTitle,
                ButtonPosition.cardAction,
                ButtonPosition.subCardAction,
                DisplayPosition.tableTopSlot,
                DisplayPosition.cnArraySubAreaCard,
                ButtonPosition.arrayTableOperate,
                ButtonPosition.pageRightButton,
                ButtonPosition.arraySubAreaCardOperate,
                ButtonPosition.pageDidMount,
                ButtonPosition.tabEvent,
                ButtonPosition.filterEvent,
                DisplayPosition.cnFormat,
              ];
              if (tempList.includes(position)) {
                const result = {
                  // 业务方
                  bizInfo: [
                    {
                      label: '业务组件',
                      value: 'common',
                    },
                  ],
                  category,
                  ...cnLowCodeConfig,
                  title,
                  componentName,
                  packageName,
                  component: {
                    realize: () => {
                      return VisualEngine.designer?.getComponentsMap?.()[
                        componentName
                      ];
                    },
                  },
                };
                if (configure?.length > 0) {
                  result.configure = configure;
                }
                return result;
              }
            }
          }
        }
      }
    }
  }
}

function getRunTimeBizComponent(name) {
  if (name) {
    let result;
    const componentsMap = VisualEngine?.designer?.getComponentsMap?.();
    if (componentsMap && componentsMap[name]) {
      result = {
        componentName: name,
        component: {
          realize: () => {
            return componentsMap[name];
          },
        },
      };
    } else if (window.ConeRenderEngine) {
      const components = getRealComponents();
      if (components?.length > 0) {
        const com = components.find((item) => item.name === name);
        if (com && com.module) {
          result = {
            componentName: name,
            component: {
              realize: () => {
                return com.module;
              },
            },
          };
        }
      }
    } else {
      const com = getExtComponent(name);
      if (com) {
        result = {
          componentName: com.name,
          component: {
            realize: () => {
              return com.module;
            },
          },
        };
      }
    }
    if (isPlainObject(result)) {
      result.isBizComponent = true;
    }
    return result;
  }
}

function getRealComponents() {
  const components = window?.ConeRenderEngine?.core?.components;
  if (isArrayNotEmpty(components)) {
    return components;
  } else {
    return window?.renderContext?.rawComponents || [];
  }
}

function getAllRunTimeBizComponentMap() {
  const result = {};
  const components = getRealComponents();
  if (isArrayNotEmpty(components)) {
    components.forEach((item) => {
      const { name, module } = item || {};
      if (name && module) {
        result[name] = module;
      }
    });
  }
  return result;
}

// 处理设计态的mokelay请求url
const handleDesignMokelayUrl = (url) => {
  const domain = window.getCnLowcodeStoreItem?.('__next_cone_domain__');
  if (domain && domain?.value) {
    return `${location.protocol}//${domain.value}${url}`;
  }
  return preMokelayDomain + url;
};

function getRealizeValue(v) {
  if (v && typeof v.realize === 'function') {
    return v.realize();
  }
  return v;
}

const symbolList = ['>=', '<=', '>', '<', '!==', '!=', '===', '==', '='];
function compileTextExpr(str) {
  if (typeof str === 'string' && str.length > 0) {
    const firstSymbol = symbolList.find((item) => str.includes(item));
    if (firstSymbol) {
      let attr;
      let value;
      try {
        const list = str.split(firstSymbol);
        if (Array.isArray(list) && list.length > 0) {
          let left = trim(list[0]);
          let right = trim(list[1]);
          left = left.replaceAll('"', '');
          left = left.replaceAll("'", '');
          if (left && right) {
            attr = left;
            const tempSymbol = ['"', '"', "'"];
            const tempSymbolFirst = tempSymbol.find((item) =>
              right.includes(item),
            );
            if (tempSymbolFirst) {
              right = right.slice(
                right.indexOf(tempSymbolFirst) + 1,
                right.lastIndexOf(tempSymbolFirst),
              );
            }
            if (right) {
              const temp = Number(right);
              if (right === 'null') {
                value = null;
              } else if (
                (right === 'true' || right === 'false') &&
                !tempSymbolFirst
              ) {
                value = Boolean(right);
              } else if (isNumber(temp) && !isNaN(temp) && !tempSymbolFirst) {
                value = temp;
              } else {
                value = right;
              }
            }
          }
        }
      } catch (e) {}
      if (firstSymbol && attr && value !== undefined) {
        switch (firstSymbol) {
          case '>':
            return (record) => {
              return record?.[attr] > value;
            };
            break;
          case '<':
            return (record) => {
              return record?.[attr] < value;
            };
            break;
          case '>=':
            return (record) => {
              return record?.[attr] >= value;
            };
            break;
          case '<=':
            return (record) => {
              return record?.[attr] <= value;
            };
            break;
          case '===':
            return (record) => {
              return record?.[attr] === value;
            };
            break;
          case '==':
          case '=':
            return (record) => {
              return record?.[attr] == value;
            };
            break;
          case '!==':
          case '!=':
            return (record) => {
              return record?.[attr] !== value;
            };
            break;
        }
      }
    } else if (str === 'true') {
      return true;
    } else if (str === 'false') {
      return false;
    } else {
      return (record) => {
        return record?.[str];
      };
    }
  }
  return str;
}

function compileLeft(str) {
  let left = trim(str);
  let attr;
  let urlParamsKey;
  let dataSourceName;
  if (left) {
    left = left.replaceAll('"', '');
    left = left.replaceAll("'", '');
    if (left) {
      if (left.startsWith(`${__urlParams__}.`)) {
        attr = __urlParams__;
        urlParamsKey = left.replace(`${__urlParams__}.`, '');
      } else if (left.startsWith(`${__ds__}`)) {
        const index = left.lastIndexOf(`${__ds__}`);
        if (index > 0) {
          attr = str.slice(0, index + 6);
          urlParamsKey = str.slice(index + 7);
          dataSourceName = str.slice(6, index);
        }
      } else {
        attr = left;
      }
    }
  }
  return {
    attr,
    urlParamsKey,
    dataSourceName,
  };
}

function compileTextExpr2(str, type) {
  if (!str) {
    str = '';
  }
  let attr;
  let value;
  let symbol;
  let realType;
  let urlParamsKey;
  let dataSourceName;
  try {
    if (typeof str === 'string' && str.length > 0) {
      symbol = symbolList.find((item) => str.includes(item));
      try {
        let left;
        let right;
        if (symbol) {
          const list = str.split(symbol);
          left = trim(list[0]);
          left = left.replaceAll('"', '');
          left = left.replaceAll("'", '');
          right = trim(list[1]);
        } else {
          left = str;
        }

        if (left) {
          const leftResult = compileLeft(left);
          if (leftResult.attr) {
            attr = leftResult.attr;
          }
          if (leftResult.urlParamsKey) {
            urlParamsKey = leftResult.urlParamsKey;
          }
          if (leftResult.dataSourceName) {
            dataSourceName = leftResult.dataSourceName;
          }
        }
        if (right) {
          const tempSymbol = ['"', '"', "'"];
          const tempSymbolFirst = tempSymbol.find((item) =>
            right.includes(item),
          );
          if (tempSymbolFirst) {
            right = right.slice(
              right.indexOf(tempSymbolFirst) + 1,
              right.lastIndexOf(tempSymbolFirst),
            );
            realType = 'string';
          } else if (right === 'true' || right === 'false') {
            realType = 'boolean';
          } else {
            const temp = Number(right);
            if (isNumber(temp) && !isNaN(temp)) {
              realType = 'number';
            }
          }
          if (right) {
            if (!type) {
              type = realType;
            }
            if (type === 'boolean') {
              value = right === 'true';
            } else if (type === 'number') {
              const temp = Number(right);
              if (isNumber(temp) && !isNaN(temp)) {
                value = temp;
              } else {
                value = undefined;
              }
            } else if (type === 'string') {
              value = right;
            } else {
              value = right;
            }
          }
        }
      } catch (e) {}
    }
  } catch (e) {}

  return {
    attr,
    value,
    symbol,
    type: realType,
    urlParamsKey,
    dataSourceName,
  };
}

function transTextExprToFunction(str) {
  const expr = compileTextExpr2(str);
  if (expr) {
    const { attr, value, symbol, urlParamsKey, dataSourceName } = expr;
    try {
      if (attr && symbol) {
        if (attr.startsWith(__ds__)) {
          if (urlParamsKey && dataSourceName) {
            switch (symbol) {
              case '>':
                return (record, params, state) => {
                  return get(state?.[dataSourceName], urlParamsKey) > value;
                };
              case '<':
                return (record, params, state) => {
                  return get(state?.[dataSourceName], urlParamsKey) < value;
                };
              case '>=':
                return (record, params, state) => {
                  return get(state?.[dataSourceName], urlParamsKey) >= value;
                };
              case '<=':
                return (record, params, state) => {
                  return get(state?.[dataSourceName], urlParamsKey) <= value;
                };
              case '===':
              case '==':
              case '=':
                if (value === undefined || value === null || value === '') {
                  return (record, params, state) => {
                    return !get(state?.[dataSourceName], urlParamsKey);
                  };
                } else {
                  return (record, params, state) => {
                    return get(state?.[dataSourceName], urlParamsKey) === value;
                  };
                }
              case '!==':
              case '!=':
                if (value === undefined || value === null || value === '') {
                  return (record, params, state) => {
                    return !!get(state?.[dataSourceName], urlParamsKey);
                  };
                } else {
                  return (record, params, state) => {
                    return get(state?.[dataSourceName], urlParamsKey) !== value;
                  };
                }
            }
          }
        } else if (attr === __urlParams__) {
          if (urlParamsKey) {
            switch (symbol) {
              case '>':
                return (record, params) => {
                  return params?.[urlParamsKey] > value;
                };
              case '<':
                return (record, params) => {
                  return params?.[urlParamsKey] < value;
                };
              case '>=':
                return (record, params) => {
                  return params?.[urlParamsKey] >= value;
                };
              case '<=':
                return (record, params) => {
                  return params?.[urlParamsKey] <= value;
                };
              case '===':
              case '==':
              case '=':
                if (value === undefined || value === null || value === '') {
                  return (record, params) => {
                    return !params?.[urlParamsKey];
                  };
                } else {
                  return (record, params) => {
                    return params?.[urlParamsKey] === value;
                  };
                }
              case '!==':
              case '!=':
                if (value === undefined || value === null || value === '') {
                  return (record, params) => {
                    return !!params?.[urlParamsKey];
                  };
                } else {
                  return (record, params) => {
                    return params?.[urlParamsKey] !== value;
                  };
                }
            }
          }
        } else if (attr.startsWith(`${__record__}.`)) {
          const realAttr = attr.slice(`${__record__}.`.length);
          if (realAttr) {
            switch (symbol) {
              case '>':
                return (record) => {
                  return record?.[realAttr] > value;
                };
              case '<':
                return (record) => {
                  return record?.[realAttr] < value;
                };
              case '>=':
                return (record) => {
                  return record?.[realAttr] >= value;
                };
              case '<=':
                return (record) => {
                  return record?.[realAttr] <= value;
                };
              case '===':
              case '==':
              case '=':
                if (value === undefined || value === null || value === '') {
                  return (record) => {
                    return !record?.[realAttr];
                  };
                } else {
                  return (record) => {
                    return record?.[realAttr] === value;
                  };
                }
              case '!==':
              case '!=':
                if (value === undefined || value === null || value === '') {
                  return (record) => {
                    return !!record?.[realAttr];
                  };
                } else {
                  return (record) => {
                    return record?.[realAttr] !== value;
                  };
                }
            }
          }
        }
      }
    } catch (e) {}
  }
}

export function executeFunction(func, ...rest) {
  if (typeof func === 'function') {
    let result;
    try {
      result = func(...rest);
    } catch (e) {}
    return result;
  }
}

function handlePrototypeCondition(
  prototypeList = [],
  componentName,
  primaryKey,
) {
  if (prototypeList?.length > 0) {
    return prototypeList.map((item) => {
      let newItem = item;
      if (isPlainObject(item)) {
        newItem = { ...item };
        newItem.__optType = componentName;
      }
      if (!newItem?.condition) {
        newItem.condition = function (prop) {
          return condition(prop, componentName, primaryKey);
        };
      }
      return newItem;
    });
  }
  return prototypeList;
}

export function getItem(
  componentMap,
  position,
  componentName,
  propKey,
  extraQueryParams,
) {
  let result;
  if (componentName) {
    let item = componentMap[componentName];
    if (!item) {
      item = getBizComponent(componentName, position);
    }
    if (typeof item === 'function') {
      item = executeFunction(item, { position });
    }
    let flag = true;
    if (item && item.position && item.position.includes(position)) {
    } else {
      flag = false;
    }
    if (isPlainObject(extraQueryParams)) {
      for (const key in extraQueryParams) {
        if (key && Array.isArray(item?.[key])) {
          if (item[key].includes(extraQueryParams[key])) {
          } else {
            flag = false;
          }
        }
      }
    }
    if (flag) {
      if (!item.label) {
        item.label = item.title;
      }
      if (!item.value) {
        item.value = item.componentName;
      }
      if (propKey) {
        result = item[propKey];
      } else {
        result = item;
      }
    }
  }
  return result;
}

export function getItemPrototypeListByPosition(config) {
  const { position, primaryKey, componentMap } = config;
  const defaultList = Object.keys(componentMap);
  const bizComponentNameList = getBizComponentNameList();
  let prototypeList = [];
  const allComponentList = uniq([...defaultList, ...bizComponentNameList]);
  allComponentList.forEach((name) => {
    const item = getItem(componentMap, position, name) || {};
    const { getPrototypeList, configure = [] } = item;
    if (typeof getPrototypeList === 'function') {
      const temp = getPrototypeList(position);
      if (temp && temp.length > 0) {
        prototypeList = [
          ...prototypeList,
          ...handlePrototypeCondition(temp, name, primaryKey),
        ];
      }
    } else if (configure?.length > 0) {
      prototypeList = [
        ...prototypeList,
        ...handlePrototypeCondition(configure, name, primaryKey),
      ];
    }
  });
  return prototypeList;
}

export function getItemListByPosition(config) {
  const { position, componentMap, extraQueryParams } = config;
  const result = [];
  const defaultList = Object.keys(componentMap);
  const bizComponentNameList = getBizComponentNameList();
  const allComponentList = uniq([...defaultList, ...bizComponentNameList]);
  allComponentList.forEach((name) => {
    const component = getItem(
      componentMap,
      position,
      name,
      null,
      extraQueryParams,
    );
    if (component) {
      const { bizInfo = [] } = component;
      if (bizInfo.length > 0) {
        bizInfo.forEach((item) => {
          const { label, value } = item;
          const existGroup = result.find((item2) => item2.value === value);
          if (existGroup) {
            existGroup?.children.push(component);
          } else {
            result.push({
              title: label,
              value,
              children: [component],
            });
          }
        });
        return;
      }
      result.push(component);
    }
  });
  return result;
}

export function getRunTimeItem(componentMap, componentName) {
  let result;
  if (componentName) {
    result = componentMap[componentName];
    if (!result) {
      result = getRunTimeBizComponent(componentName);
    }
  }
  return result;
}

export function getItemDefaultProps(componentMap, position, componentName) {
  const func = getItem(
    componentMap,
    position,
    componentName,
    'getDefaultProps',
  );
  if (typeof func === 'function') {
    return func();
  }
}

export function isTextExpr(str) {
  if (typeof str === 'string' && str.length > 0) {
    if (str === __blank__) {
      return {
        prefix: __blank__,
      };
    } else if (str.startsWith(`${__record__}`)) {
      return {
        prefix: __record__,
        value: str.replace(`${__record__}.`, ''),
      };
    } else if (str.startsWith(__urlParams__)) {
      return {
        prefix: __urlParams__,
        value: str.replace(`${__urlParams__}.`, ''),
      };
    } else if (str.startsWith(__ds__)) {
      if (str.endsWith(__ds__)) {
        const dataSourceName = str.slice(6, str.lastIndexOf(__ds__));
        return {
          prefix: __ds__,
          dataSourceName,
        };
      } else {
        const index = str.indexOf(`${__ds__}.`);
        if (index > 0) {
          const dataSourceName = str.slice(6, index);
          const value = str.slice(index + 7);
          if (value && dataSourceName) {
            return {
              prefix: __ds__,
              value,
              dataSourceName,
            };
          }
        }
      }
    }
  }
  return false;
}

export function calculateTextExprValue(originValue, config = {}) {
  const textExpr = isTextExpr(originValue);
  const {
    urlParamsDataSource,
    recordDataSource,
    state,
    extraParamList = [],
    tableCurrentRow,
    extraParam,
    getExtraParam,
  } = config;
  if (textExpr) {
    const { prefix, value: textExprValue, dataSourceName } = textExpr;
    let temp;
    if (prefix === __blank__) {
      temp = undefined;
    } else if (prefix === __record__) {
      temp = recordDataSource;
    } else if (prefix === __urlParams__) {
      temp = urlParamsDataSource;
    } else if (prefix === __ds__ && dataSourceName) {
      temp = state?.[dataSourceName];
    }
    if (textExprValue) {
      return get(temp, textExprValue);
    } else {
      return temp;
    }
  } else if (typeof originValue === 'function') {
    try {
      let extra = extraParamList;
      if (!Array.isArray(extra)) {
        extra = [];
      }
      return originValue(recordDataSource, state, ...extra);
    } catch (e) {
      return;
    }
  } else if (isValueObjectExpr(originValue)) {
    const { group, param, secondParam, thirdParam } = originValue;
    if (group && param) {
      let result;
      let realExtraParam = extraParam;
      if (typeof getExtraParam === 'function') {
        realExtraParam = executeFunction(getExtraParam);
      }
      const objExprArgMap = {
        [__record__]: recordDataSource,
        [__dataSource__]: state,
        [__tableCurrentRow__]: tableCurrentRow,
        [__extraParam__]: realExtraParam,
      };
      if (secondParam) {
        result = get(
          objExprArgMap,
          `${group}.${param}.${secondParam}${
            thirdParam ? `.${thirdParam}` : ''
          }`,
        );
      } else {
        result = get(objExprArgMap, `${group}.${param}`);
      }
      return result;
    }
  }
  return originValue;
}

export function filterUndefined(obj) {
  if (isPlainObject(obj)) {
    const keys = Object.keys(obj);
    if (keys?.length > 0) {
      const result = {};
      Object.keys(obj).forEach((key) => {
        if (key && obj[key] !== undefined) {
          result[key] = obj[key];
        }
      });
      return result;
    }
  }
  return obj;
}

function uuid(len = 4) {
  return customAlphabet('abcdefghijklmnopqrstuvwxyz', len)();
}

function getFormDefaultValue(defaultParams, config) {
  const {
    urlParamsDataSource,
    state,
    position,
    isDesign,
    formConfig,
    getExtraParam,
    ignoreDefaultSelectFormRequest,
  } = config || {};
  const {
    dataOrigin,
    defaultValue = {},
    requestConfig = {},
    afterRequest = {},
  } = defaultParams || {};
  if (dataOrigin === 'static') {
    const result = calculateTextExprValue(defaultValue, {
      urlParamsDataSource,
      state,
    });
    if (result) {
      if (isPlainObject(result) && Object.keys(result).length > 0) {
        return result;
      } else if (
        isArray(result) &&
        result.length > 0 &&
        typeof defaultValue !== 'function'
      ) {
        const temp = {};
        const formItemFormatMap = {};
        const formItemComponentNameMap = {};
        const formItemMap = {};
        if (isArray(formConfig)) {
          formConfig.forEach((item) => {
            const { name, componentName, options } = item;
            if (name && options?.outputFormat) {
              formItemFormatMap[name] = options.outputFormat;
            }
            formItemComponentNameMap[name] = componentName;
            formItemMap[name] = item;
          });
        }
        result.forEach((item) => {
          const { name, valueType, value } = item;
          if (name && valueType && value !== undefined) {
            if (valueType === 'buildIn') {
              if (isPlainObject(value)) {
                const time = calculateTime(value, formItemFormatMap[name], {
                  range: formItemComponentNameMap?.[name] === 'RangePicker',
                });
                if (time) {
                  temp[name] = time;
                }
              }
            } else if (valueType === 'DefaultSelect') {
              const current = formItemMap[name];
              if (
                allowSelectFirstComponentList.includes(current?.componentName)
              ) {
                const { options } = current || {};
                if (options?.dataOrigin === dataOriginStatic) {
                  const { dataSource } = options;
                  let ds = dataSource;
                  if (typeof dataSource === 'function') {
                    ds = dataSource(state);
                  }
                  if (isArray(ds) && ds.length > 0) {
                    if (typeof value === 'number') {
                      const tempDs = ds[value];
                      if (tempDs?.value !== undefined) {
                        temp[name] = tempDs.value;
                      }
                    }
                  }
                } else if (options?.dataOrigin === dataOriginRequest) {
                  if (
                    isEmptyButNotZero(temp[name]) &&
                    ignoreDefaultSelectFormRequest !== true
                  ) {
                    temp[name] = item;
                  }
                }
              }
            } else if (valueType === 'SelectFromDataSource') {
              temp[name] = calculateTextExprValue(value, {
                state,
              });
            } else {
              temp[name] = value;
            }
          }
        });
        if (Object.keys(temp).length > 0) {
          return temp;
        }
      }
    }
  } else if (dataOrigin === 'request') {
    const realUrl = getRealRequestUrl({
      requestConfig,
      state,
      extraParam: getExtraParam?.(),
    });
    if (realUrl) {
      return makeRequest({
        buttonConfig: {
          options: {
            requestConfig: {
              ...requestConfig,
              url: realUrl,
              dynamicUrl: undefined,
            },
          },
        },
        urlParamsDataSource,
        recordDataSource: {},
        state,
        needSuccessToast: false,
        isDesign,
        getExtraParam,
      }).then((res) => {
        const res2 = getRealResponse(res);
        const { success, data } = res2;
        if (success) {
          if (isPlainObject(data) && Object.keys(data).length > 0) {
            return data;
          }
        }
      });
    }
  }
}

function getNodeFieldList(prop, options) {
  const { componentNameList = [] } = options || {};
  const nodeData = [];
  const nodesMap = prop.getNode?.()?.document?.nodesMap;
  const currentId = prop?.getNode?.()?.id;
  if (nodesMap?.forEach) {
    nodesMap.forEach((item) => {
      const { id } = item;
      if (componentNameList.includes(item.componentName)) {
        if (item?.getPropValue('isCnTable')) {
          const columns = item.getPropValue('columns') || [];
          if (columns?.length > 0) {
            const temp = {
              label: `表格${id.replace('node', '')}`,
              key: id,
              children: [],
            };
            columns.forEach((column) => {
              const { dataIndex } = column;
              let { title } = column;
              title = handleI18nLabel(title);
              if (title && dataIndex) {
                temp.children.push({
                  label: `${title}(${dataIndex})`,
                  key: `${id}_${dataIndex}`,
                  originValue: dataIndex,
                  originLabel: title,
                  originConfig: column,
                  parentComponent: item.componentName,
                });
              }
            });
            if (temp.children.length > 0) {
              nodeData.unshift(temp);
            }
          }
        } else if (
          item.componentName === 'CnFilter' ||
          item.componentName === 'CnForm' ||
          item.componentName === 'CnFormDialog'
        ) {
          if (item.id !== currentId) {
            const config = item.getPropValue('config') || [];
            let tempName = '筛选栏';
            if (item.componentName === 'CnFormDialog') {
              tempName = '表单弹窗';
            } else if (item.componentName === 'CnForm') {
              tempName = '表单';
            }
            const temp = {
              label: tempName + id.replace('node', ''),
              key: id,
              children: [],
            };
            if (config?.length > 0) {
              config.forEach((con) => {
                const { name, componentName } = con;
                let { label } = con;
                label = handleI18nLabel(label);
                if (label && name) {
                  const tempItem = {
                    label: `${label}(${name})`,
                    key: `${id}_${name}`,
                    originValue: name,
                    originLabel: label,
                    originConfig: con,
                    parentComponent: item.componentName,
                  };
                  if (componentName) {
                    tempItem.componentName = componentName;
                  }
                  temp.children.push(tempItem);
                }
              });
              if (temp.children.length > 0) {
                nodeData.push(temp);
              }
            }
          }
        }
      }
    });
  }
  return nodeData;
}

function createDataSource(dsConfig) {
  if (dsConfig) {
    const { id, name, description } = dsConfig;
    // const dataSourceList = getDataSourceList();
    if (id && name && VisualEngine) {
      const dataSource = VisualEngine?.context?.getManager('dataPool');
      return dataSource?.addItem({
        description,
        dpType: 'VALUE',
        id,
        initialData: '',
        isGlobal: false,
        name,
        protocal: 'VALUE',
      });
    }
  }
}

function makeFormItemSchema(config) {
  const {
    formItemConfig,
    isDesign,
    urlParams,
    formValue,
    state,
    usedComponentList,
    formProps,
    _context,
    formInstance,
    getFormInstance,
    formStepInstance,
    isInCnFilterPro,
    componentRequestFinish,
    customDecoratorComponent,
    parentPosition,
    index,
    decoratorDefaultProps,
  } = config || {};
  const { formStyle } = formProps || {};
  const { readOnly: formReadOnly, allowCopy, layoutMode } = formStyle || {};

  const {
    label,
    name,
    componentName,
    rules = [],
    options = {},
    disabled,
    hidden,
    hasClear,
    tip,
    readOnly,
    placeholder,
    extra,
    colSpan,
    readOnlyClick,
    span,
    mobileProps,
    __advancedCodeConfig__,
    rightButtons,
  } = formItemConfig || {};
  const { handleProps } = __advancedCodeConfig__ || {};
  const title = calculateTextExprValue(label, config);
  const { dataOrigin } = options;

  let componentProps = { ...options };
  // formItem专用
  if (formReadOnly === true && allowCopy === true) {
    componentProps.readOnlyProps = {
      allowCopy: true,
    };
  }
  // formItem专用
  if (isPlainObject(readOnlyClick)) {
    if (readOnlyClick?.optType) {
      const action = getButtonAction({
        ...readOnlyClick,
        position: ButtonPosition.arrayTableCell,
      });
      if (action && !isDesign) {
        if (!componentProps.readOnlyProps) {
          componentProps.readOnlyProps = {};
        }

        if (typeof action === 'function') {
          componentProps.readOnlyProps.onClick = (e, field) => {
            action(
              {
                buttonConfig: readOnlyClick,
                state: _context?.state,
                urlParamsDataSource: urlParams,
                _context,
                position: ButtonPosition.arrayTableCell,
                formProps,
              },
              { field },
            );
          };
          componentProps.readOnlyProps.className = 'cn-table-link-cell';
        }
      }
    }
  }

  // 共用
  if (hasClear !== undefined) {
    componentProps.hasClear = hasClear;
  }
  // 共用
  if (placeholder) {
    componentProps.placeholder = calculateTextExprValue(placeholder, {
      recordDataSource: formValue || {},
      state,
    });
  }
  const componentDefine = getRunTimeItem(filterItemComponentMap, componentName);
  if (componentDefine) {
    const { isBizComponent } = componentDefine;
    if (isBizComponent === true) {
      componentProps[_getContext] = () => {
        return _context;
      };
    }
    let component = componentDefine?.component;
    component = getRealizeValue(component);
    const tempFormBeforeHandler = componentDefine?.tempFormBeforeHandler;
    const formBeforeHandler = component?.formBeforeHandler;
    if (tempFormBeforeHandler) {
      componentProps = tempFormBeforeHandler(componentProps, {
        isDesign,
        urlParamsDataSource: urlParams,
        recordDataSource: formValue,
        state,
        isInForm: true,
        formInstance,
        _context,
        getFormInstance,
        formItemConfig,
        componentRequestFinish,
        formProps,
        parentPosition,
      });
    } else if (formBeforeHandler) {
      componentProps = formBeforeHandler(componentProps, {
        isDesign,
        urlParamsDataSource: urlParams,
        recordDataSource: formValue,
        state,
        isInForm: true,
        formInstance,
        _context,
        getFormInstance,
        formItemConfig,
        componentRequestFinish,
        formProps,
      });
    }
  }
  const formItemProps = {};
  // filterItem专用
  if (isInCnFilterPro) {
    if (typeof span === 'number') {
      formItemProps.colSpan = span;
    }
    formItemProps.mobileProps = mobileProps;
  }
  // 共用
  if (typeof colSpan === 'number') {
    formItemProps.colSpan = colSpan;
  }
  // if (Array.isArray(componentProps?.dataSource) && componentProps?.dataSource.length > 0 && dataOrigin === 'static') {
  //   formItemProps.enum = componentProps.dataSource;
  //   delete componentProps.dataSource;
  // }
  if (name && componentName) {
    // let isHidden;
    // if(!isObjectExpr(hidden)) {
    //   isHidden = executeObjectExpr(hidden, {
    //     [__dataSource__]: _context?.state,
    //     [__formValue__]: formValue,
    //     [__filterValue__]: formValue,
    //   },formValue || {}, state);
    // }
    // let isDisabled;
    // if(!isObjectExpr(disabled)) {
    //   isDisabled = executeObjectExpr(disabled, {
    //     [__dataSource__]: _context?.state,
    //     [__formValue__]: formValue,
    //     [__filterValue__]: formValue,
    //   }, formValue || {}, state);
    // }
    // const isReadOnly = executeObjectExpr(readOnly, {
    //   [__dataSource__]: _context?.state,
    //   [__formValue__]: formValue || {},
    //   [__filterValue__]: formValue || {},
    // }, formValue || {}, state);
    let realComponentProps;
    if (typeof handleProps === 'function') {
      const extraProps = executeFunction(
        handleProps,
        { ...componentProps },
        _context?.state,
      );
      if (isPlainObject(extraProps)) {
        realComponentProps = merge(extraProps, { ...componentProps });
      }
    }
    if (!realComponentProps) {
      realComponentProps = { ...componentProps };
    }
    const formItem = {
      title,
      'x-component': componentName,
      'x-component-props': realComponentProps,
      'x-decorator': customDecoratorComponent || 'CnFormItem',
      ...formItemProps,
    };
    formItem['x-data'] = {
      disabled,
      hidden,
      readOnly,
    };
    formItem['x-decorator-props'] = {
      ...decoratorDefaultProps,
    };
    if (isArrayNotEmpty(rightButtons)) {
      formItem['x-decorator-props'].rightExtra = makeButtons({
        buttons: rightButtons?.map((item) => {
          return {
            ...item,
            position: ButtonPosition.formItemRightButton,
            style: {
              marginLeft: '8px',
            },
          };
        }),
        _context,
        state: _context?.state,
        urlParamsDataSource: _context?.state?.urlParams || {},
        recordDataSource: formValue || {},
        formInstance,
        getFormInstance,
      });
    }
    if (layoutMode === 'single' && colSpan === 1) {
      formItem['x-decorator-props'].style = {
        maxWidth: '50%',
      };
    }
    if (tip) {
      if (typeof tip === 'string') {
        formItem['x-decorator-props'].tip = tip;
      } else if (typeof tip === 'function') {
        formItem['x-decorator-props'].tip = executeFunction(
          tip,
          formValue || {},
          state,
        );
      }
    }
    if (extra) {
      if (typeof extra === 'string') {
        formItem['x-decorator-props'].extra = extra;
      } else if (isPlainObject(extra)) {
        const { redirectType, text } = extra;
        const url = calculateUrl(extra, {
          urlParamsDataSource: urlParams,
          recordDataSource: formValue,
          state,
        });
        const extraProps = {};
        if (redirectType === 'open') {
          extraProps.target = '_blank';
        }
        if (url) {
          extraProps.href = url;
        }
        formItem['x-decorator-props'].extra = (
          <a {...extraProps}>
            {calculateTextExprValue(text, {
              recordDataSource: formValue || {},
              state,
            })}
          </a>
        );
      } else if (typeof extra === 'function') {
        formItem['x-decorator-props'].extra = executeFunction(
          extra,
          formValue || {},
          state,
        );
      }
    }
    if (isDesign && componentName !== 'FormItemSlot') {
      formItem[
        'x-decorator-props'
      ].className = `l2-cn-form-item l2-cn-form-item-${index}`;
    }
    // if (typeof isReadOnly === 'boolean') {
    //   formItem.readOnly = isReadOnly;
    // }
    // if (typeof isHidden === 'boolean') {
    //   formItem['x-hidden'] = isHidden;
    //   // formItem['x-display'] = isHidden ? 'none' : 'visible'
    // }
    // if (typeof isDisabled === 'boolean') {
    //   formItem['x-disabled'] = isDisabled;
    // }
    usedComponentList.push(componentName);
    if (rules.length > 0) {
      const temp = transRulesToValidator(rules, {
        formValue,
        state,
        position: ValidatorPosition.form,
        isInCnFilterPro,
      });
      formItem['x-validator'] = temp;
    }
    if (componentDefine) {
      const formItemBeforeHandler = componentDefine?.formItemBeforeHandler;
      if (formItemBeforeHandler) {
        formItemBeforeHandler(formItem, {
          formItemConfig,
          formProps,
          isDesign,
          usedComponentList,
          urlParams,
          formValue,
          state,
          _context,
          formInstance,
          formStepInstance,
          getFormInstance,
          parentPosition,
        });
      }
    }
    const ds = formItem['x-component-props']?.dataSource;
    if (dataOrigin === 'static') {
      if (Array.isArray(ds) && ds.length > 0) {
        formItem.enum = ds;
      }
      if (formItem?.['x-component-props']?.dataSource) {
        if ([DisplayPosition.cnArraySubAreaCard].includes(parentPosition)) {
        } else {
          delete formItem['x-component-props'].dataSource;
        }
      }
    }
    return formItem;
  }
}

// 表单项排序是否正确
function isFormListCurrent(list) {
  let isCurrent = true;
  if (Array.isArray(list)) {
    let needCheck = false;
    for (const index in list) {
      const item = list[index];
      if (
        +index === 0 &&
        item.componentName &&
        item.componentName !== 'CnCard' &&
        item.componentName !== 'CnCardSubCard' &&
        item.componentName !== 'CnFormStepItem' &&
        item.componentName !== 'CnFormTabItem'
      ) {
        needCheck = true;
      } else if (
        needCheck &&
        ((item.componentName && item.componentName === 'CnCard') ||
          item.componentName === 'CnCardSubCard' ||
          item.componentName !== 'CnFormStepItem' ||
          item.componentName !== 'CnFormTabItem')
      ) {
        isCurrent = false;
        break;
      }
    }
  }
  return isCurrent;
}

function transDataSourceToMap(list) {
  const result = {};
  if (Array.isArray(list) && list.length > 0) {
    list.forEach((item) => {
      if (
        item.value !== undefined &&
        item.value !== null &&
        item.label !== undefined
      ) {
        result[item.value] = item.label;
      }
    });
  }
  return result;
}

function handleSelectRequestConfig(config, extra) {
  const {
    componentProps,
    isDesign,
    urlParamsDataSource,
    recordDataSource,
    state,
    ignoreHandleParam,
    handleDynamicUrl,
  } = config || {};
  const { dynamicParams } = extra || {};
  if (isPlainObject(componentProps)) {
    const { dataOrigin, extraProps } = componentProps;
    if (dataOrigin === 'request') {
      if (handleDynamicUrl === true) {
        const { requestConfig } = componentProps;
        const { useDynamicUrl, dynamicUrl } = requestConfig || {};
        if (useDynamicUrl === true && typeof dynamicUrl === 'function') {
          const realUrl = getRealRequestUrl({
            requestConfig,
            state,
          });
          if (
            realUrl &&
            typeof realUrl === 'string' &&
            componentProps.requestConfig
          ) {
            componentProps.requestConfig.url = realUrl;
            componentProps.requestConfig.dynamicUrl = undefined;
          }
        }
      }
      // if (componentProps?.requestConfig?.url) {
      delete componentProps.dataSource;
      // }
      if (componentProps?.requestConfig?.serviceType === 'mokelay') {
        componentProps.requestConfig.method = 'post';
        if (isDesign && componentProps?.requestConfig?.url) {
          componentProps.requestConfig.url = handleDesignMokelayUrl(
            componentProps.requestConfig?.url,
          );
        }
      } else if (componentProps?.requestConfig) {
        componentProps.requestConfig.withCredentials = true;
      }
      if (
        ignoreHandleParam !== true &&
        Array.isArray(componentProps?.requestConfig?.params) &&
        componentProps?.requestConfig?.params.length > 0
      ) {
        if (dynamicParams) {
          // 闭包 保存变量
          componentProps.requestConfig.formatParam = (() => {
            const { params } = componentProps.requestConfig;
            return function () {
              const realParams = handleRequestParams(params, {
                urlParamsDataSource,
                recordDataSource,
                state,
              });
              return realParams || {};
            };
          })();
          delete componentProps.requestConfig.params;
        } else {
          const realParams = handleRequestParams(
            componentProps?.requestConfig?.params,
            {
              urlParamsDataSource,
              recordDataSource,
              state,
            },
          );
          if (realParams) {
            if (componentProps?.requestConfig?.method === 'post') {
              componentProps.requestConfig.data = realParams;
              delete componentProps.requestConfig.params;
            } else {
              componentProps.requestConfig.params = realParams;
            }
          }
        }
      }
      if (
        componentProps?.requestConfig?.serviceType !== 'mock' &&
        typeof componentProps?.requestConfig?.resultProcessFunc === 'function'
      ) {
        componentProps.requestConfig.formatResult = (res) => {
          let newRes = getRealResponse(res);
          try {
            newRes = componentProps?.requestConfig?.resultProcessFunc(newRes);
          } catch (e) {
            console.error('请求结果回调执行失败', e);
          }

          if (Array.isArray(newRes?.data)) {
            newRes = newRes.data;
          } else if (Array.isArray(newRes?.data?.dataSource)) {
            newRes = newRes?.data?.dataSource;
          }
          return newRes;
        };
      } else if (
        componentProps?.requestConfig?.serviceType === 'mock' &&
        isPlainObject(componentProps?.requestConfig?.mockData)
      ) {
        componentProps.requestConfig.formatResult = () => {
          return cloneDeep(componentProps?.requestConfig?.mockData?.data);
        };
      }
      if (componentProps?.searchRemote) {
        componentProps.filterLocal = false;
        if (componentProps?.searchKey && componentProps?.requestConfig) {
          componentProps.requestConfig.searchKey = componentProps.searchKey;
        }
      }
      if (componentProps?.requestConfig) {
        componentProps.requestConfig.throttleWait = 800;
        if (extraProps?.enableRemoteLazyLoad === true) {
          componentProps.enableRemoteLazyLoad = true;
          if (extraProps?.remoteLazyLoadKey) {
            componentProps.requestConfig.remoteLazyLoadKey =
              extraProps.remoteLazyLoadKey;
          }
        }

        const execute = calculateRequestExecute(
          componentProps?.requestConfig,
          {
            [__formValue__]: recordDataSource,
            [__filterValue__]: recordDataSource,
            [__dataSource__]: state,
          },
          recordDataSource || {},
          state,
        );
        // const execute = executeObjectExpr(componentProps.requestConfig?.execute, {}, recordDataSource || {}, state)
        if (execute === false) {
          componentProps.requestConfig.manual = true;
        }
        handleFormUrlencodedContentType(componentProps.requestConfig);
      }

      if (componentProps?.requestWhenFocus === false) {
      } else {
        componentProps.onVisibleChange = visibleRun.bind(null, {
          requestConfig: componentProps?.requestConfig,
          state,
          recordDataSource,
        });
      }

      delete componentProps.searchRemote;
      delete componentProps.searchKey;
      delete componentProps.extraProps;
      delete componentProps.requestWhenFocus;
      componentProps.showSearch = true;
    } else {
      delete componentProps.requestConfig;
    }
  }
}

function handleSelectDataSource(config) {
  const { componentProps, state, recordDataSource } = config || {};
  if (isPlainObject(componentProps)) {
    const { dataOrigin, dataSource } = componentProps;
    if (dataOrigin === 'static') {
      if (isArrayNotEmpty(dataSource)) {
        const newDataSource = dataSource.map((item) => {
          const { disabled } = item || {};
          if (typeof disabled === 'function') {
            item.disabled = executeFunction(disabled, recordDataSource, state);
          }
          return item;
        });
        if (isArrayNotEmpty(newDataSource)) {
          componentProps.dataSource = newDataSource;
        }
      } else if (typeof dataSource === 'function') {
        try {
          const temp = dataSource(state);
          if (Array.isArray(temp)) {
            componentProps.dataSource = temp;
          }
        } catch (e) {}
      } else if (isValueObjectExpr(dataSource)) {
        const tempDs = calculateTextExprValue(dataSource, { state });
        if (Array.isArray(tempDs)) {
          componentProps.dataSource = tempDs;
        }
      }
      if (!Array.isArray(componentProps.dataSource)) {
        componentProps.dataSource = [];
      }
    }
  }
}

function handlePageDataSource(config) {
  const { componentProps, state } = config || {};
  if (isPlainObject(componentProps)) {
    const { dataOrigin, dataSource } = componentProps;
    if (dataOrigin === 'static') {
      if (typeof dataSource === 'function') {
        try {
          componentProps.dataSource = dataSource(state);
        } catch (e) {}
      } else if (isValueObjectExpr(dataSource)) {
        componentProps.dataSource = calculateTextExprValue(dataSource, {
          state,
        });
      }
    }
  }
}

function isRequestConfig(requestConfig) {
  if (requestConfig) {
    const { url, serviceType } = requestConfig;
    if (url && serviceType) {
      return true;
    }
  }
  return false;
}
function makeButtons(config) {
  const {
    buttons,
    _context,
    state,
    urlParamsDataSource,
    recordDataSource,
    extraParamList = [],
    formInstance,
    handleBtnProps,
    useProxyButton,
    arrayTableCurrentRow,
    arrayBaseField,
    arrayBaseFieldIndex,
    getFormInstance,
    parentPosition,
  } = config;
  if (Array.isArray(buttons) && buttons.length > 0) {
    const result = [];
    // eslint-disable-next-line guard-for-in
    for (const index in buttons) {
      const item = buttons[index];
      const {
        iconType,
        primaryKey,
        optType,
        options = {},
        children,
        position,
        hidden,
        disabled,
        getExtraParam,
        buttonHoverInfo,
        onClick,
        ...rest
      } = item;
      const isHidden = executeObjectExpr(
        hidden,
        {
          [__filterValue__]: recordDataSource || {},
          [__formValue__]: recordDataSource || {},
          [__dataSource__]: state,
          [__arrayTableCurrentRow__]: arrayTableCurrentRow,
        },
        recordDataSource || {},
        state,
        arrayBaseFieldIndex,
        formInstance?.values,
      );
      if (isHidden) {
        continue;
      }
      const isDisabled = executeObjectExpr(
        disabled,
        {
          [__filterValue__]: recordDataSource || {},
          [__formValue__]: recordDataSource || {},
          [__dataSource__]: state,
          [__arrayTableCurrentRow__]: arrayTableCurrentRow,
        },
        recordDataSource || {},
        state,
        arrayBaseFieldIndex,
        formInstance?.values,
      );
      const action = getButtonAction({ ...item, position });
      const componentDefine = getRunTimeItem({}, optType);
      const getRenderDom = getButtonItem(position, optType, 'getRenderDom');
      const btnProps = {
        ...rest,
      };
      if (isDisabled === true) {
        btnProps.disabled = isDisabled;
      }
      if (componentDefine?.component) {
        const component = getRealizeValue(componentDefine.component);
        if (component) {
          result.push(
            React.createElement(component, {
              children,
              ...btnProps,
              buttonConfig: item,
              _context,
              [_getFormValues]: () => {
                return formInstance?.values;
              },
              formInstance: undefined,
              arrayBaseField,
              arrayBaseFieldIndex,
              getFormInstance,
            }),
          );
          continue;
        }
      } else if (typeof getRenderDom === 'function') {
        const dom = executeFunction(getRenderDom, {
          _context,
          buttonConfig: item,
          state,
          urlParamsDataSource,
          recordDataSource: {
            realize: () => {
              return formInstance?.values;
            },
          },
          btnProps,
        });
        if (dom) {
          result.push(dom);
          continue;
        }
      }
      if (action) {
        const actionConfig = {
          buttonConfig: item,
          position,
          state,
          urlParamsDataSource,
          recordDataSource: {
            realize: () => {
              return formInstance?.values;
            },
          },
          formInstance,
          _context,
          getExtraParam,
          arrayTableCurrentRow,
          arrayBaseField,
          arrayBaseFieldIndex,
          ...extraParamList,
          getFormInstance,
          parentPosition,
        };
        if (typeof onClick === 'function') {
          btnProps.onClick = (...arg) => {
            executeFunction(onClick, ...arg);
            action(actionConfig, ...arg);
          };
        } else {
          btnProps.onClick = action.bind(null, actionConfig);
        }
      }
      if (typeof handleBtnProps === 'function') {
        handleBtnProps(btnProps);
      }
      let ButtonCom = CnButton;
      if (useProxyButton === true) {
        ButtonCom = CnButtonProxy;
      }
      const ButtonItem = (
        <ButtonCom key={index} {...btnProps}>
          {renderIcon(iconType)}
          {children}
        </ButtonCom>
      );
      let Button = ButtonItem;
      const { needHover, hoverInfo = {} } = buttonHoverInfo || {};
      let { title, content, align, handleProps } = hoverInfo;
      const restProps = executeFunction(handleProps, {}, state);
      if (needHover && (title || content)) {
        title = calculateTextExprValue(title, {
          recordDataSource,
          state,
          getExtraParam,
        });
        content = calculateTextExprValue(content, {
          recordDataSource,
          state,
          getExtraParam,
        });
        Button = (
          <CnBalloon
            trigger={ButtonItem}
            title={title}
            closable={false}
            align={align}
            {...restProps}
          >
            {content}
          </CnBalloon>
        );
      }
      result.push(Button);
    }
    return result;
  }
  return null;
}
function handleSuccessMessage(res) {
  const { msg, extra } = res || {};
  const { type } = extra || {};
  let resultType = 'success';
  if (messageTypeMap[type]) {
    resultType = type;
  }
  CnMessage[resultType](
    msg || $i18n.get({ id: 'RequestSuccessful', dm: '请求成功' }),
  );
}

function handleEvents(config = []) {
  const eventMap = {};
  if (Array.isArray(config) && config.length > 0) {
    for (const item of config) {
      const { events, name } = item || {};
      if (name && Array.isArray(events) && events.length > 0) {
        eventMap[name] = events;
      }
    }
  }
  return eventMap;
}
function handleFormat(time, format) {
  if (time) {
    if (format) {
      return time.format(format);
    } else {
      return time?.valueOf();
    }
  }
  return time;
}

function calculateTime(value, format, config) {
  const { range } = config;
  if (isPlainObject(value)) {
    try {
      const { num, rela, time, unit } = value;
      if (rela && num !== undefined && unit) {
        let temp = dayjs()[rela](num, unit);
        if (temp) {
          if (range) {
            let start;
            let end;
            if (rela === 'subtract') {
              start = handleFormat(temp, format);
              end = handleFormat(dayjs(), format);
            } else if (rela === 'add') {
              start = handleFormat(dayjs(), format);
              end = handleFormat(temp, format);
            }
            return [start, end];
          } else if (time) {
            if (time !== 'now') {
              temp = temp[time]('d');
            }
            return handleFormat(temp, format);
          }
        }
      }
    } catch (e) {}
  }
}

function removeDataSourceByNode(current) {
  if (current?.id) {
    const dataSourceName = current.getPropValue(_dataSourceName);
    if (dataSourceName) {
      const node = VisualEngine?.designer?.currentDocument?.nodesMap?.get?.(
        current.id,
      );
      if (!node) {
        const ds = getDataSourceByName(dataSourceName);
        if (ds && ds.id) {
          VisualEngine?.context?.getManager?.('dataPool')?.removeItem?.(ds.id);
        }
      }
    }
  }
}

function getNodeTitle(node: any) {
  const { propsData, componentName } = node || {};

  const { tableName } = propsData || {};
  if (componentName === 'CnTable') {
    return tableName || '表格';
  }

  if (['CnDialog', 'CnFormDialog'].includes(componentName)) {
    return getDialogTitle(node);
  }

  const { title } = propsData || {};
  return handleComponentTitle(handleI18nLabel(title));
}

const getDialogTitle = (node: any) => {
  const { propsData, componentName } = node || {};
  const { title, titleDescription } = propsData || {};
  if (!['CnDialog', 'CnFormDialog'].includes(componentName)) {
    return title;
  }

  let dialogTitle = componentName === 'CnDialog' ? '弹窗_' : '表单弹窗_';
  if (title) {
    dialogTitle += handleComponentTitle(handleI18nLabel(title));
  }
  if (titleDescription) {
    dialogTitle += ` (${titleDescription})`;
  }

  return dialogTitle;
};

function handleI18nLabel(label) {
  if (isPlainObject(label) && label.type === 'cn-i18n') {
    return label.dm || '';
  }
  return label;
}

function calculateUrl(config, extra) {
  const { url, urlParams = [] } = config || {};
  if (url) {
    let search = '';
    const { urlParamsDataSource, recordDataSource, state, extraParamList } =
      extra || {};
    if (urlParams && urlParams.length > 0) {
      const temp = handleRequestParams(urlParams, {
        urlParamsDataSource,
        recordDataSource,
        state,
        extraParamList,
      });
      search = qs.stringify(temp);
    }

    let realUrl = calculateTextExprValue(url, {
      urlParamsDataSource,
      recordDataSource,
      state,
      extraParamList,
    });
    if (typeof realUrl === 'string' && realUrl.length > 0) {
      if (realUrl.indexOf('?') !== -1) {
        realUrl += `&${search}`;
      } else if (search) {
        realUrl += `?${search}`;
      }
      return realUrl;
    }
  }
}

function generateDataSource(config) {
  const { componentName } = config || {};
  if (componentName) {
  }
  let dataSourceList = [];
  dataSourceList = getDataSourceList();
  let index = '';
  const first = dataSourceList?.find(
    (item) => item.value === `${componentName}`,
  );
  if (first) {
    index = generateIndex(dataSourceList, componentName);
  }
  if (Engine) {
    const componentPrototype =
      Engine?.designer?.getComponentMeta?.(componentName)?.prototype;
    const dataSource = Engine?.context?.getManager('dataPool');
    const ds = dataSource?.addItem({
      description: `${
        componentPrototype?.options?.title || componentName
      }${index}的数据源`,
      dpType: 'VALUE',
      id: '',
      initialData: '',
      isGlobal: false,
      name: `${componentName}${index}`,
      protocal: 'VALUE',
    });
    if (ds?.name) {
      return ds;
    }
  }
}

function setDataToDs(config) {
  const { data, _dataSourceName, _context, _dataSource } = config || {};
  if (isPlainObject(data) && _dataSourceName && _context) {
    _context?.setState({
      [_dataSourceName]: {
        ..._dataSource,
        ...data,
      },
    });
  }
}

function needRequestRemote(config, defaultParams) {
  const { dataOrigin, defaultValue } = defaultParams || {};
  if (dataOrigin === dataOriginStatic && isArray(defaultValue)) {
    const { name, componentName, options } = config || {};
    if (name && allowSelectFirstComponentList.includes(componentName)) {
      const { dataOrigin, requestConfig } = options || {};
      if (
        dataOrigin === dataOriginRequest &&
        (requestConfig?.url || requestConfig?.useDynamicUrl)
      ) {
        const current = defaultValue.find(
          (item) => item?.name === name && item?.valueType === 'DefaultSelect',
        );
        if (current?.name) {
          return current;
        }
      }
    }
  }
  return false;
}

function getNodeById(config) {
  const { field, id } = config;
  let result;
  if (id) {
    const nodesMap = field?.getNode?.()?.document?.nodesMap;
    if (nodesMap?.values()) {
      for (const item of nodesMap.values()) {
        if (item?.id === id) {
          result = item;
          break;
        }
      }
    }
  }
  return result;
}

function getRealRequestUrl(config) {
  const { requestConfig, state, extraParam } = config || {};
  let result;
  if (requestConfig) {
    const { dynamicUrl, useDynamicUrl, url } = requestConfig;
    result = url;
    if (useDynamicUrl === true && typeof dynamicUrl === 'function') {
      const temp = executeFunction(dynamicUrl, state, extraParam || {});
      if (typeof temp === 'string') {
        result = temp;
      } else {
        result = '';
      }
    }
  }
  return result;
}

function getDownloadProps(config) {
  const { url, extraParams } = config || {};
  let downloadProps;
  if (typeof url === 'string') {
    downloadProps = {
      url,
    };
  } else if (isRequestConfig(url)) {
    downloadProps = {
      service: transRequestConfigToRemote({
        requestConfig: url,
        ...extraParams,
      }),
    };
  }
  return downloadProps;
}

function renderIcon(type) {
  if (typeof type === 'string' && type.length > 0) {
    return <CnIcon type={type} />;
  }
  return undefined;
}

function executeEventWithoutJS(config) {
  const {
    eventType,
    events,
    _context,
    position,
    urlParamsDataSource,
    recordDataSource,
    formInstance,
  } = config || {};
  if (eventType && Array.isArray(events) && events.length > 0) {
    for (const item of events) {
      const { name: eventName } = item;
      if (eventName === eventType) {
        const action = getButtonAction({ ...item, position });
        if (typeof action === 'function') {
          action({
            buttonConfig: {
              ...item,
              position,
              options: {
                ...item,
              },
            },
            position,
            state: _context?.state,
            urlParamsDataSource,
            recordDataSource,
            _context,
            formInstance,
          });
        }
      }
    }
  }
}

function isEmptyButNotZero(value) {
  return value === undefined || value === null || value === '';
}

function makeFilterItem(config) {
  const {
    filterItemConfig,
    formValue,
    _context,
    isDesign,
    urlParams,
    recordDataSource,
    componentRequestFinish,
  } = config || {};
  const {
    label = '',
    name,
    componentName,
    span,
    required,
    requiredMessage,
    options = {},
    placeholder,
    hidden,
    disabled,
    rules = [],
    hasClear,
    tip,
    mobileProps,
  } = filterItemConfig || {};
  const componentDefine = getFilterRunTimeItem(componentName);
  if (componentName && componentDefine) {
    const isDisabled = executeObjectExpr(
      disabled,
      {
        [__formValue__]: formValue,
        [__filterValue__]: formValue,
        [__dataSource__]: _context?.state,
      },
      formValue,
      _context?.state,
    );
    let { component, filterItemBeforeHandler, getRenderDom } = componentDefine;
    const filterItemProps = {
      label,
      name,
      componentName,
      span,
      required,
      requiredMessage,
      disabled: isDisabled,
      mobileProps,
    };
    if (tip) {
      filterItemProps.tip = tip;
    }
    // 协议更改兼容
    delete options.placeholder;
    let componentProps = cloneDeep({ hasClear, placeholder, ...options });
    component = getRealizeValue(component);
    const filterBeforeHandler = component?.filterBeforeHandler;
    if (filterBeforeHandler) {
      componentProps = filterBeforeHandler(componentProps, {
        isDesign,
        urlParamsDataSource: urlParams,
        recordDataSource,
        state: _context?.state,
        componentRequestFinish,
        filterItemConfig,
      });
    }
    const isHidden = executeObjectExpr(
      hidden,
      {
        [__formValue__]: formValue,
        [__filterValue__]: formValue,
        [__dataSource__]: _context?.state,
      },
      formValue,
      _context?.state,
    );
    if (isHidden) {
      return;
    }
    // 处理校验
    if (rules.length > 0) {
      filterItemProps.rules = transRulesToValidator(rules, {
        formValue,
        state: _context?.state,
        position: ValidatorPosition.filter,
      });
    }
    filterItemBeforeHandler &&
      filterItemBeforeHandler(filterItemProps, {
        componentProps,
        isDesign,
        urlParamsDataSource: urlParams,
        recordDataSource,
        state: _context?.state,
      });
    let dom;
    if (typeof getRenderDom === 'function') {
      dom = getRenderDom(config);
    }
    return {
      filterItemProps: filterUndefined(filterItemProps),
      component,
      componentProps,
      dom,
    };
  }
}

function handleComponentTitle(title) {
  if (typeof title === 'string') {
    return title;
  } else if (isPlainObject(title)) {
    const realTitle = handleI18nLabel(title);
    if (typeof realTitle === 'string') {
      return realTitle;
    }
    const { mock, type, value } = title;
    if (type === 'JSExpression') {
      if (mock) {
        return mock;
      } else {
        return '动态标题弹窗';
      }
    }
    return '动态标题';
  }
  return title;
}

export function getArrayTableFieldList(param) {
  const { config, arrayTableName } = param || {};
  if (arrayTableName && isArrayNotEmpty(config)) {
    const result = [];
    config.forEach((item) => {
      const { label, name } = item || {};
      if (name) {
        let realLabel = handleI18nLabel(label) || name;
        if (typeof realLabel !== 'string') {
          realLabel = name;
        }
        result.push({
          label: realLabel,
          value: `${arrayTableName}.${__arrayTableCurrentRow__}.${name}`,
        });
      }
    });
    return result;
  }
}

function isArrayNotEmpty(list) {
  return Array.isArray(list) && list.length > 0;
}

function handlePlaceholder(componentProps) {
  const { placeholder } = componentProps || {};
  if (typeof placeholder === 'string' && placeholder.includes(',')) {
    const arr = placeholder.split(',');
    if (arr.length === 2) {
      componentProps.placeholder = arr;
    }
  }
}

async function executeFlowList(config) {
  const result = [];
  const { list, position, _context } = config || {};
  if (isArrayNotEmpty(list) && _context) {
    for (const index in list) {
      const item = list[index];
      const { active, optType } = item || {};
      const isActive = executeObjectExpr(
        active,
        {
          [__dataSource__]: _context?.state,
        },
        {},
        _context?.state,
      );
      if (isActive === true) {
        let action = getButtonAction({
          ...item,
          position,
        });
        if (!action) {
          const componentDefine = getFilterRunTimeItem(optType);
          const component = getRealizeValue(componentDefine?.component);
          if (typeof component?.action === 'function') {
            action = component.action;
          }
        }
        let flowResult;
        if (typeof action === 'function') {
          flowResult = await action({
            position,
            needSuccessToast: false,
            buttonConfig: { ...item },
            _context,
            state: _context?.state,
            urlParamsDataSource: _context?.state?.urlParams || {},
            recordDataSource: {},
          });
        }
        const handleFlowResult = getButtonItem(
          position,
          optType,
          'handleFlowResult',
        );
        if (typeof handleFlowResult === 'function') {
          flowResult = handleFlowResult(flowResult);
        }
        if (flowResult && _context) {
          let realIndex = +index;
          if (realIndex === 0) {
            realIndex = '';
          }
          _context.state.valueOf[optType + realIndex] = flowResult;
        }
        result.push(flowResult);
      }
    }
  }
  return result;
}

function clearState(config) {
  const { _context } = config || {};
  if (_context?.state) {
    const flowDataKeys = Object.keys(_context.state.valueOf);
    if (Array.isArray(flowDataKeys) && flowDataKeys.length > 0) {
      flowDataKeys.forEach((key) => {
        if (key?.includes(__stateValueOfSplit__)) {
        } else {
          // FIXME 需要将动作编排的临时存储数据清掉
          // _context.state.valueOf[key] = undefined;
        }
      });
    }
  }
}

function handleOriginList(
  originList,
  labelKey,
  valueKey,
  groupExprName,
  extraConfig,
) {
  const result = [];
  const { dsName } = extraConfig || {};
  if (isArrayNotEmpty(originList)) {
    originList.forEach((item2) => {
      const { componentName } = item2;
      const label = handleI18nLabel(item2[labelKey]);
      const value = item2[valueKey];
      if (value) {
        const newLabel = label ? `${label}（${value}）` : value;
        const temp = {
          label: newLabel,
          text: newLabel,
          value: `${groupExprName}.${value}`,
        };
        if (
          componentName === 'RangePicker' ||
          componentName === 'RangeTimePicker'
        ) {
          temp.children = [
            {
              label: '开始时间',
              value: `${temp.value}[0]`,
            },
            {
              label: '结束时间',
              value: `${temp.value}[1]`,
            },
          ];
        }
        if (componentName === 'CnArrayTable' && item2?.name && dsName) {
          result.push({ ...temp });
          temp.label = `${temp.label} 的额外数据`;
          temp.children = [
            {
              label: arrayTableCurrentRowLabel,
              value: `state.valueOf.${dsName}.${item2.name}.${__arrayTableCurrentRowByWhole__}`,
            },
            {
              label: arrayTableCurrentRowIndex,
              value: `state.valueOf.${dsName}.${item2.name}.${__arrayTableCurrentRowIndexByWhole__}`,
            },
            {
              label: tableCurrentRowByOperateClickLabel,
              value: `state.valueOf.${dsName}.${item2.name}.${__arrayTableCurrentRow__}`,
            },
            {
              label: tableCurrentRowIndexByOperateClickLabel,
              value: `state.valueOf.${dsName}.${item2.name}.${__arrayTableCurrentRowIndex__}`,
            },
          ];
        }
        if (componentName == 'CnArraySubAreaCard' && item2?.name && dsName) {
          result.push({ ...temp });
          temp.label = `${temp.label} 的额外数据`;
          temp.children = [
            {
              label: arrayCardCurrentRowLabel,
              value: `state.valueOf.${dsName}.${item2.name}.${__arrayCardCurrentRowByWhole__}`,
            },
            {
              label: arrayCardCurrentRowIndex,
              value: `state.valueOf.${dsName}.${item2.name}.${__arrayCardCurrentRowIndexByWhole__}`,
            },
          ];
        }
        result.push(temp);
        // if(handleComposeComponent && componentName === 'Compose') {
        //   const tempChildren = handleOriginList(item2?.options?.config, 'label','name',`${groupExprName}.${value}` )
        //   if(isArrayNotEmpty(tempChildren)) {
        //     result = [...result, ...tempChildren]
        //   }
        // }
      }
    });
  }
  return result;
}

function getArrayTableCurrentIndex(field) {
  let currentIndex;
  if (field) {
    const segments = field?.path?.segments;
    currentIndex = segments?.[1];
    if (currentIndex !== 'number') {
      currentIndex = segments?.[segments?.length - 2];
    }
  }
  return currentIndex;
}

function setAdvancedConfigToProps(props) {
  if (isPlainObject(props?.__advancedConfig__)) {
    Object.keys(props.__advancedConfig__).forEach((key) => {
      const tempV = props.__advancedConfig__[key];
      if (key && !isEmptyButNotZero(tempV)) {
        props[key] = tempV;
      }
    });
    delete props.__advancedConfig__;
  }
}

function isRecursionComponent(componentName) {
  return recursionComponentList.includes(componentName);
}

function handlePropsDynamicUrl(props, extraConfig) {
  const { field } = extraConfig || {};
  if (
    props?.dataOrigin === dataOriginRequest &&
    isPlainObject(props.requestConfig)
  ) {
    const { getRequestParams } = props;
    let _params;
    const extraParam = {};
    if (typeof getRequestParams === 'function') {
      _params = getRequestParams();
    }
    extraParam[__arrayTableCurrentRow__] =
      getArrayTableCurrentRowByField(field) || {};

    if (
      typeof props.requestConfig.dynamicUrl === 'function' &&
      props.requestConfig.useDynamicUrl === true
    ) {
      const realUrl = getRealRequestUrl({
        requestConfig: props.requestConfig,
        ..._params,
        extraParam,
      });
      if (realUrl && typeof realUrl === 'string') {
        props.requestConfig.url = realUrl;
      }
    }
  }
}

function getArrayTableCurrentRowByField(field) {
  if (field) {
    const tempIndex = getArrayTableCurrentIndex(field);
    const index = Number(tempIndex);
    if (isNumber(index) && !isNaN(index)) {
      const temp = field.query('..').value();
      const currentRow = temp?.[index];
      if (isPlainObject(currentRow)) {
        return currentRow;
      }
    }
  }
}

function getArrayTableCurrentRowByField2(field) {
  if (field) {
    const segments = field?.path?.segments;
    const realSegments = segments.slice(0, -1);
    const currentRow = field?.form?.getValuesIn?.(realSegments);
    if (isPlainObject(currentRow)) {
      return currentRow;
    }
  }
}



/**
 *
 * @param field
 * @param lastListName
 * @returns
 * 列子：obj.list.1.name.xxx  当传入了lastListName的时候为list的时候，则获取的是 index为1的那一行数据
 */
function getLastListCurrentRowByField(field, lastListName: string) {
  if (field) {
    const segments = field?.path?.segments;

    let sliceIndex = segments.length;

    if(lastListName) {
      let isStop = false;
      while(!isStop) {
        sliceIndex--;

        if(
          sliceIndex <=0 ||
          (segments[sliceIndex-1]===lastListName && isFieldRecursionComponent(segments.slice(0, sliceIndex)))
          // 匹配到最近的字段，且如果是递归类组件，则表示正确
        ) {
          isStop = true;
        }

      }
    }
    const realSegments = segments.slice(0, segments[sliceIndex-1]===lastListName ? sliceIndex + 1 : -1);
    const currentRow = field?.form?.getValuesIn?.(realSegments);
    if (isPlainObject(currentRow)) {
      return currentRow;
    }
  }

  function isFieldRecursionComponent(path) {
    const componentName = field.form.getFieldState(path)?.component?.[0]
    return isRecursionComponent(componentName);
  }
}

function makeALink(config) {
  const { linkExpr, _context, recordDataSource } = config || {};
  const { redirectType, text } = linkExpr;
  if (text) {
    const url = calculateUrl(linkExpr, {
      urlParamsDataSource: _context?.state?.urlParams || {},
      recordDataSource: {},
      state: _context?.state,
    });
    const extraProps = {};
    if (redirectType === 'open') {
      extraProps.target = '_blank';
    }
    if (url) {
      extraProps.href = url;
    }
    return (
      <a {...extraProps}>
        {calculateTextExprValue(text, {
          recordDataSource: recordDataSource || {},
          state: _context?.state,
        })}
      </a>
    );
  }
  return null;
}

function handleListI18nLabel(list, key) {
  if (isArrayNotEmpty(list)) {
    list?.forEach((item) => {
      if (item?.[key]) {
        item[key] = handleI18nLabel(item[key]);
      }
    });
  }
}

function getFlowListDataSource(config) {
  const result = [];
  const { currentFlowIndex, flowList } = config || {};
  if (
    typeof currentFlowIndex === 'number' &&
    Array.isArray(flowList) &&
    flowList.length > 0
  ) {
    const existFlowList = flowList.slice(0, currentFlowIndex);
    if (existFlowList?.length > 0) {
      result.push(...createSelectList(existFlowList, __dataSource__));
    }
  }
  return result;
}

function dialogOpen(config) {
  const { dialogNodeId, data, _context } = config || {};
  if (dialogNodeId && typeof _context?.$ === 'function') {
    const dialogNode = _context.$(dialogNodeId);
    if (dialogNode) {
      return new Promise((resolve) => {
        setTimeout(() => {
          const p = dialogNode?.open?.(data);
          if (typeof p?.then === 'function') {
            p.then((res) => {
              setTimeout(() => {
                resolve(true);
              });
            });
          } else {
            setTimeout(() => {
              resolve(true);
            });
          }
        });
      });
    }
  }
}

function dialogClose(config) {
  const { dialogNodeId, data, _context } = config || {};
  if (dialogNodeId && typeof _context?.$ === 'function') {
    const dialogNode = _context.$(dialogNodeId);
    if (dialogNode) {
      return new Promise((resolve) => {
        setTimeout(() => {
          const p = dialogNode?.close?.(data);
          if (typeof p?.then === 'function') {
            p.then(() => {
              setTimeout(() => {
                resolve(true);
              });
            });
          } else {
            setTimeout(() => {
              resolve(true);
            });
          }
        });
      });
    }
  }
}

function tableLoad(config) {
  const { _bindTable, _context } = config || {};
  function reloadOneTable(id) {
    if (typeof id === 'string') {
      const table = _context?.$(id);
      table?.load?.();
    }
  }

  if (_bindTable && _context) {
    if (Array.isArray(_bindTable)) {
      _bindTable.forEach((item) => {
        reloadOneTable(item);
      });
    } else {
      reloadOneTable(_bindTable);
    }
  }
}

function handleFormUrlencodedContentType(requestConfig) {
  if (
    requestConfig?.serviceType === 'http' &&
    requestConfig?.contentType === formUrlencoded
  ) {
    requestConfig.headers = {
      'content-type': formUrlencoded,
    };
  }
}

// 处理请求的额外配置项
function handleRequestExtraConfig(requestConfig, state) {
  if (isPlainObject(requestConfig?.__extraConfig__)) {
    const { headers } = requestConfig.__extraConfig__;
    if (headers) {
      let realHeaders;
      if (isPlainObject(headers)) {
        realHeaders = headers;
      } else if (typeof headers === 'function') {
        realHeaders = executeFunction(headers, {}, state);
      }
      if (isPlainObject(realHeaders)) {
        if (isPlainObject(requestConfig?.headers)) {
          requestConfig.headers = { ...requestConfig.headers, ...realHeaders };
        } else {
          requestConfig.headers = realHeaders;
        }
      }
    }
  }
}
// 统一处理请求的headers
function handleRequestConfig(config) {
  const { headers, state, requestConfig } = config || {}
  if (isPlainObject(requestConfig)) {
    if (isPlainObject(headers)) {
      let realHeaders;
      if (isPlainObject(headers)) {
        realHeaders = headers;
      } else if (typeof headers === 'function') {
        realHeaders = executeFunction(headers, requestConfig?.headers, state);
      }
      if (isPlainObject(realHeaders)) {
        if (isPlainObject(requestConfig?.headers)) {
          requestConfig.headers = { ...requestConfig.headers, ...realHeaders };
        } else {
          requestConfig.headers = realHeaders;
        }
      }
    }
  }
}

function handleFormUrlencodedData(requestConfig) {
  if (
    requestConfig?.serviceType === 'http' &&
    requestConfig?.contentType === formUrlencoded &&
    requestConfig?.method === 'post' &&
    isPlainObject(requestConfig?.data)
  ) {
    requestConfig.data = qs.stringify(requestConfig.data);
  }
}

function calculateWaitComponentList(config, defaultParams) {
  const result = {
    waitComponentList: [],
    waitComponentMap: {},
    configMap: {},
  };
  if (isArrayNotEmpty(config)) {
    config.forEach((item, index) => {
      const { name } = item || {};
      result.configMap[name] = item;
      const need = needRequestRemote(item, defaultParams);
      if (need) {
        result.waitComponentList.push(name);
        result.waitComponentMap[name] = need;
      }
    });
  }
  return result;
}

// 计算请求是否执行
function calculateRequestExecute(requestConfig, ...arg) {
  if (requestConfig) {
    const originalExecute = requestConfig?.execute;
    const tempExecute = requestConfig?.__extraConfig__?.execute;
    if (
      isObjectExpr(tempExecute) ||
      typeof tempExecute === 'function' ||
      typeof tempExecute === 'boolean'
    ) {
      return executeObjectExpr(tempExecute, ...arg);
    } else if (typeof originalExecute === 'function') {
      return executeObjectExpr(originalExecute, ...arg);
    }
  }
}

// 计算表单字段的缩进
function handleFormConfigIndent(config) {
  const { config: fieldConfig, formInfo, children } = config || {};
  const { isFormStep, isFormTab, hasCard } = formInfo || {};
  if (isArrayNotEmpty(fieldConfig)) {
    fieldConfig.forEach((item, index) => {
      const { componentName, name } = item || {};
      if (name && componentName) {
        let backgroundColor;
        let borderTopLeftRadius;
        let padding;
        let marginLeft;
        let borderLeft;
        const currentDom = children?.[index];
        if (isFormStep || isFormTab) {
          if (
            componentName === 'CnFormStepItem' ||
            componentName === 'CnFormTabItem'
          ) {
            backgroundColor = '#cbd9ff';
            borderTopLeftRadius = '5px';
            padding = '3px';
            marginLeft = '0px';
          } else {
            borderTopLeftRadius = '0px';
            padding = '0px';
            marginLeft = '12px';
            backgroundColor = '#f0f2ff';
          }
        } else if (hasCard) {
          if (componentName === 'CnCard') {
            backgroundColor = '#dbdfff';
            borderTopLeftRadius = '5px';
            padding = '3px';
            marginLeft = '0px';
          } else if (componentName === 'CnCardSubCard') {
            borderTopLeftRadius = '0px';
            padding = '0px';
            marginLeft = '6px';
            backgroundColor = '#dbdfff';
            padding = '3px';
            borderLeft = '3px solid #284cc0';
          } else {
            borderTopLeftRadius = '0px';
            padding = '0px';
            marginLeft = '12px';
            backgroundColor = '#f0f2ff';
          }
        }
        if (currentDom?.style) {
          if (index === 0) {
            currentDom.setAttribute('handled', 'handled');
          }
          currentDom.style.borderTopLeftRadius = borderTopLeftRadius;
          currentDom.style.padding = padding;
          currentDom.style.marginLeft = marginLeft;
          currentDom.style.backgroundColor = backgroundColor;
          if (borderLeft) {
            currentDom.style.borderLeft = borderLeft;
          }
        }
      }
    });
  }
}

function getFormInfo(originalConfig) {
  let firstFormStep;
  let isFormStep = false;
  let isFormTab = false;
  let hasCard = false;
  let firstFormTabIndex = 0;
  if (isArrayNotEmpty(originalConfig)) {
    for (const index in originalConfig) {
      const item = originalConfig[index];
      if (item?.componentName === 'CnFormStepItem') {
        firstFormStep = item;
        isFormStep = true;
        break;
      } else if (item?.componentName === 'CnFormTabItem') {
        isFormTab = true;
        firstFormTabIndex = +index;
        break;
      } else if (item?.componentName === 'CnCard') {
        hasCard = true;
      }
    }
  }
  return {
    firstFormStep,
    isFormStep,
    isFormTab,
    firstFormTabIndex,
    hasCard,
  };
}

// 处理设计态时的表单项缩进
function handleDesignFormConfig(tconfig) {
  const { nodeId, newFormConfig } = tconfig || {};
  const oldNodeConfig = cacheFormConfig[nodeId];
  if (oldNodeConfig) {
    const { formConfigLength, formConfig } = oldNodeConfig;
    if (formConfigLength === newFormConfig?.length) {
      let isSame = true;
      for (const index in formConfig) {
        const newItem = newFormConfig?.[index];
        const oldItem = formConfig[index];
        if (newItem?.componentName !== oldItem?.componentName) {
          isSame = false;
          break;
        }
      }
      if (isSame === true) {
        const first = document.querySelector('.lc-sortable')?.children?.[0];
        const handled = first?.getAttribute?.('handled');
        if (handled === 'handled') {
          return;
        }
      }
    }
  }
  console.info('design: form handle indent');
  handleFormConfigIndent({
    config: newFormConfig,
    formInfo: getFormInfo(newFormConfig) || {},
    children: document.querySelector('.lc-sortable')?.children,
  });
  cacheFormConfig[nodeId] = {
    formConfigLength: newFormConfig?.length,
    formConfig: newFormConfig?.map((item) => {
      return {
        componentName: item.componentName,
        name: item.name,
      };
    }),
  };
}

function getPermissionGranted() {
  return {
    // 如果didmount时允许设置页面级 就把这个开出来 但是要加state入参 这里字段名固定 优先级 页面级别的高
    // ...(state?.[__selfPermissionGranted__] || {}),
    ...(iceStore?.PERMISSION_GRANTED || {}),
  };
}

function handleFilterDefaultValue(origin, extra) {
  if (isPlainObject(extra)) {
    return { ...origin, ...extra };
  }
  return origin;
}

function mergeHandleProps(config) {
  const { handleProps, componentProps, _context } = config || {};
  if (typeof handleProps === 'function') {
    const tempProps = executeFunction(
      handleProps,
      { ...componentProps },
      _context?.state,
    );
    if (isPlainObject(tempProps)) {
      return merge(tempProps, { ...componentProps });
    }
  }
}

// 获取变量数据源列表
function getVariableDsList(){
  const result = [...getDataSourceList({
    typeList: ['CN_VALUE'],
  }),...getDataSourceList({
    typeList: ['VALUE'],
  })?.filter(
    (item) =>
      item?.dataSourceId &&
      item.dataSourceId?.startsWith?.(
        pageDataSource,
      ),
  )]

  return result || []
}

function getJSExpressionPrototype2(config) {
  const { type: configType, prototypeConfig, offlineTip } = config || {};
  if (configType === 'form') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state) => {
  return formValues.xxxx === "xxxx";
}`,
      tip: `当前函数需要返回 true/false。
formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'table') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(record, state, index) => {
  return record.id === "xxxx";
}`,
      tip: `当前函数需要返回 true/false。
record：表格当前行的数据。
state：全部的数据，在左侧列表中选择使用。
index：表格当前行的位置。

`,
    });
  } else if (configType === 'formRequest') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state) => {
  // return formValues.xxxx;
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'arrayTableCurrentRowRequest') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, { ${__arrayTableCurrentRow__} }) => {
  return formValues.xxxx;
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
__arrayTableCurrentRow__：可编辑表格当前行的数据。
`,
    });
  } else if (configType === 'formRequestForTreeTableAsyncRequestConfig') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, { __tableCurrentRow__ }) => {
  // __tableCurrentRow__是当前行数据  从这个字段取  不要从侧边栏那里取
  // return formValues.xxxx;
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
__tableCurrentRow__: 当前行数据。
`,
    });
  } else if (configType === 'tableRequest') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(record, state, index) => {
  // return record.xxxx;
}`,
      tip: `record：表格当前行的数据。
state：全部的数据，在左侧列表中选择使用。
index：表格当前行的位置。

`,
    });
  } else if (configType === 'formJSX') {
    return {
      title: 'JSX代码',
      componentName: 'CnRowDataSetter',
      props: () => {
        const stateList = getDataSourceListWithAllPath({
          needChildren: true,
          prototypeConfig,
        });
        return {
          list: stateList,
          initialCode: `(formValues, state) => {
  // return <div>xxx字段的数据是：{formValues.xxxx}</div>;
}`,
          tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
`,
        };
      },
    };
  } else if (configType === 'select') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(state) => {
  // 需要返回数组，格式如下
  return [
    {
      label: '选项一',
      value: 'first'
    }
  ]
}`,
      tip: `当前函数需要返回数组。
`,
    });
  } else if (configType === 'tableBatchArea') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, selectedRowKeys, selectedRowRecords) => {
  // return formValues.xxxx;
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
selectedRowKeys：当前选择的数据主键列表。
selectedRowRecords：当前选择的数据列表。
`,
    });
  } else if (configType === 'base') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(arg, state) => {
  // return state.urlParams.xxx;
}`,
      tip: `
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'dataOrigin') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(arg, state) => {
        // return state.urlParams.xxx ? 'request': 'static';
      }`,
      tip: `
      state：全部的数据，在左侧列表中选择使用。
      函数返回的分别 request/static 代表 请求/静态数据
`,
    });
  } else if (configType === 'arrayTable') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, record) => {
  return record.xxxx === "xxxx";
}`,
      tip: `当前函数需要返回 true/false。
formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
record：表格当前行数据。
`,
    });
  } else if (configType === 'subAreaCard') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, record, index) => {
  return record.title;
}`,
      tip: `当前函数需要返回string。
formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
record：卡片当前行数据。
index：卡片当前行的index
`,
    });
  } else if (configType === 'breadcrumb') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `() => {
  // 需要返回数组，格式如下
  return [
    {
      children: '页面1',
    },
    {
      children: '页面2'
    }
  ]
}`,
      tip: `当前函数需要返回数组。
`,
    });
  } else if (configType === 'datepicker') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(date, mode, formValues, state) => {

}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'datepickerPreset') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(dayjs,formValues, state) => {
       // return {
        //  此刻: () => dayjs()
        // }
      }`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
dayjs 是日期处理工具
`,
    });
  } else if (configType === 'step') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(current, state) => {
  return current === 0;
}`,
      tip: `当前函数需要返回 true/false。
current：当前点击项的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'arrayTableOperate') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(record, state, index, formValues) => {
  return record.id === "xxxx";
}`,
      tip: `当前函数需要返回 true/false。
record：表格当前行的数据。
state：全部的数据，在左侧列表中选择使用。
index：表格当前行的位置。
formValues：当前表单的数据。

`,
    });
  } else if (configType === 'tab') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(currentSelect, state) => {
  // return state.urlParams.xxx;
}`,
      tip: `
currentSelect：当前选中项的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'formDialogTitle') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(openDialogMode, state) => {
  // return openDialogMode;
}`,
      tip: `
openDialogMode：本次打开的弹窗的用途: 新增(new)、编辑(edit)、详情(detail)。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'tableInitRequest') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, { currentPage, pageSize, sortList }) => {
  // return formValues.xxxx;
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
currentPage：${currentPageLabel}。
pageSize：${pageSizeLabel}。
sortList：${sortListLabel}。
`,
    });
  } else if (configType === 'messageContent') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state) => {
  // success:：成功；warning：警告；error：错误；notice：通知；help：帮助；
  // return 'success';
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'arrayTableCurrentRow') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, { ${__arrayTableCurrentRow__} }) => {
  return formValues.xxxx === "xxxx";
}`,
      tip: `当前函数需要返回 true/false。
formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
__arrayTableCurrentRow__：可编辑表格当前行的数据。
`,
    });
  } else if (configType === 'headers') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(arg, state) => {
  // return { }
}`,
      tip: `
返回值（return）必须是JSON对象格式
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'props') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(oldProps, state) => {
  // 返回额外的props属性即可，返回值将会和原props合并；
  // return {};
}`,
      tip: `
oldProps: 组件的原始oldProps
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'selectInArrayCard') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(state, { record, index }) => {
  // 返回额外的props属性即可，返回值将会和原props合并；
  // return {};
}`,
      tip: `
record: 当前行数据
index: 当前行下标
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'tableLoopRequest') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(res, state) => {
  // return res;
}`,
      tip: `
res: 请求返回的数据
state：全部的数据，在左侧列表中选择使用。
`,
    });
  } else if (configType === 'formatValue') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `({item, index, state}) => {
  // return item.xxxx;
}`,
      tip: `item：当前卡片的数据。
index：当前卡片的位置。
state：全部的数据，在左侧列表中选择使用。
`,
    })
  } else if (configType === 'pollService') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(res, state) => {
        // return res?.data;  返回true 则表示结束，false则继续轮询
      }`,
      tip: `
        res: 轮询项最后一个接口返回的数据
        state：全部的数据，在左侧列表中选择使用。
      `,
    });
  }
  if (configType === 'childTableInitRequest') {
    return getJSExpressionPrototypeTemplate({
      prototypeConfig,
      offlineTip,
      initialCode: `(formValues, state, { currentPage, pageSize, record }) => {
  // return formValues.xxxx;
}`,
      tip: `formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
currentPage：${currentPageLabel}。
pageSize：${pageSizeLabel}。
record：子母表中母表格展开行的数据。
`,
    });
  }
  return {};
}

function getJSExpressionPrototypeTemplate(config) {
  const { title, initialCode, tip, prototypeConfig, offlineTip } = config || {};
  return {
    title: `${title || '写js表达式'}${offlineTip ? '(不推荐)' : ''}`,
    componentName: 'CnRowDataSetter',
    props: () => {
      const stateList = getDataSourceListWithAllPath({
        needChildren: true,
        prototypeConfig,
      });
      return {
        list: stateList,
        initialCode,
        tip,
        offlineTip,
      };
    },
  };
}

function handleFormatChildren(children, config) {
  const { item, index, state } = config || {}
  if(children && item) {
    return React.Children.map(children, (item2) => {
      if(item2?.props?.__componentName__ === 'CnFormat') {
        return React.cloneElement(item2, {
          [__record__]: item,
          [__index__]: index,
          [__state__]: state,
        });
      }
      return item2;
    })
  }else {
    return children;
  }
}


export {
  getId,
  ID_NAME,
  FIELD_NAME,
  NAME,
  generateIndex,
  generateDataSource,
  getDataSourceList,
  transProxyToObject,
  getDsNameFromVariable,
  hidden,
  isDesignMode,
  condition,
  getBizComponentNameList,
  getBizComponent,
  getRunTimeBizComponent,
  handleDesignMokelayUrl,
  getRealizeValue,
  // isTextExprTrue,
  handlePrototypeCondition,
  compileTextExpr2,
  transTextExprToFunction,
  getDataSourceListWithAllPath,
  handleEvents,
  uuid,
  getFormDefaultValue,
  getNodeFieldList,
  getDataSourceByName,
  getDataSourceById,
  createDataSource,
  makeFormItemSchema,
  isFormListCurrent,
  transDataSourceToMap,
  handleSelectRequestConfig,
  isRequestConfig,
  makeButtons,
  handleSuccessMessage,
  handleI18nLabel,
  removeDataSourceByNode,
  getNodeTitle,
  getDialogTitle,
  executeObjectExpr,
  isObjectExpr,
  calculateUrl,
  setDataToDs,
  needRequestRemote,
  getNodeById,
  handleSelectDataSource,
  getRealRequestUrl,
  isValueObjectExpr,
  getDownloadProps,
  renderIcon,
  executeEventWithoutJS,
  isEmptyButNotZero,
  makeFilterItem,
  handleComponentTitle,
  isArrayNotEmpty,
  handlePlaceholder,
  executeFlowList,
  clearState,
  handleOriginList,
  getArrayTableCurrentIndex,
  setAdvancedConfigToProps,
  getAllRunTimeBizComponentMap,
  isRecursionComponent,
  handlePropsDynamicUrl,
  getArrayTableCurrentRowByField,
  makeALink,
  handleListI18nLabel,
  getFlowListDataSource,
  dialogOpen,
  dialogClose,
  handleFormUrlencodedContentType,
  handleFormUrlencodedData,
  calculateWaitComponentList,
  getArrayTableCurrentRowByField2,
  getLastListCurrentRowByField,
  calculateRequestExecute,
  tableLoad,
  handleFormConfigIndent,
  getFormInfo,
  handleDesignFormConfig,
  handleRequestExtraConfig,
  getPermissionGranted,
  handleFilterDefaultValue,
  handlePageDataSource,
  mergeHandleProps,
  getVariableDsList,
  handleRequestConfig,
  getJSExpressionPrototype2,
  getJSExpressionPrototypeTemplate,
  handleFormatChildren,
};
