import {
  getJSExpressionPrototype,
  getParamSetterPrototype,
} from '@/common/manager/common-style';
import { ButtonPosition } from '@/common/manager/position/button-position';
import {
  getArrayTableFieldList,
  getDialogTitle,
  getNodeById,
  handleI18nLabel,
  handleOriginList,
  isArrayNotEmpty,
  isRecursionComponent,
} from '@/common/util/util';
import { CnTooltip, Select } from '@cainiaofe/cn-ui';
import {
  __arrayTableCurrentRow__,
  __dataSource__,
  __extraParam__,
  formDialogStateLabel,
  getCommonBoolDataSource,
  getFormExprNameByPosition,
  getOpenDialogModeEnum,
  openDialogModeLabel,
} from '@/common/util/expr-const';
import {
  createButtonListSetters,
  createFilterSelectSetters,
  createTableSelectSetters,
  getButtonListByPosition,
  getButtonPrototypeListByPosition,
} from '@/common/manager/button';
import { DisplayPosition } from '@/common/manager/position/display-position';
import ExprSetter from '@/common/setter/expr-setter';
import IdSetter from '@/common/setter/id-setter';
import { createEventSetters } from './event';
import {
  dataOriginRequest,
  dataOriginStatic,
} from '@/common/util/const';

const { ActionSetter } = window.VisualEngineUtils || {};

export function getStringSetter() {
  return {
    componentName: 'StringSetter',
    title: '字符串',
  };
}

const getTableOperateRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'table', prototypeConfig: config }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tableRequest',
          prototypeConfig: config,
        }),
      ],
    },
  };
};
const getTableOperateUrlSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getParamSetterPrototype({ type: 'table', prototypeConfig: config }),
        getJSExpressionPrototype({
          type: 'tableRequest',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getTableToolAreaUrlSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getParamSetterPrototype({ type: 'filter', prototypeConfig: config }),
        getJSExpressionPrototype({
          type: 'formRequest',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getTableToolAreaRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'filter', prototypeConfig: config }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tableBatchArea',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getTableToolAreaRequestParamSetter2 = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'filter' }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'formRequest',
        }),
      ],
    },
  };
};

// 带表格当前页信息请求参数的setter
const getTableToolAreaRequestParamSetter3 = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'filterWithPagination' }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'formRequest',
        }),
      ],
    },
  };
};

const getFormRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'form', prototypeConfig: config }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'formRequest',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getFormUrlSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getParamSetterPrototype({ type: 'form', prototypeConfig: config }),
        getJSExpressionPrototype({
          type: 'formRequest',
        }),
      ],
    },
  };
};

const getFormDialogRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({
          type: 'formDialog',
          prototypeConfig: config,
        }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tableBatchArea',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getArrayTableOperateRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'arrayTable' }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tableRequest',
        }),
      ],
    },
  };
};

const getArrayTableItemEventRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'arrayTableItemEvent' }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tableRequest',
        }),
      ],
    },
  };
};

// 自增卡片中子卡片请求参数setter
const getArrayCardSubcardRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({
          type: 'arrayCardSubCardButton',
          prototypeConfig: config,
        }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'arrayTableCurrentRowRequest',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getArrayTableOperateUrlSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getParamSetterPrototype({ type: 'arrayTable' }),
        getJSExpressionPrototype({
          type: 'tableRequest',
        }),
      ],
    },
  };
};

const getStepRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'base', prototypeConfig: config }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'base',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

const getListOperateRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tableRequest',
        }),
      ],
    },
  };
};

const getStepUrlSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getParamSetterPrototype({ type: 'base' }),
        getJSExpressionPrototype({
          type: 'base',
        }),
      ],
    },
  };
};

const getTabUrlSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getStringSetter(),
        getParamSetterPrototype({ type: 'base' }),
        getJSExpressionPrototype({
          type: 'tab',
        }),
      ],
    },
  };
};

const getTabRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'base' }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'tab',
        }),
      ],
    },
  };
};

const getTreeEventRequestParamSetter = (config) => {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        getParamSetterPrototype({ type: 'tree', prototypeConfig: config }),
        getStringSetter(),
        getJSExpressionPrototype({
          type: 'base',
          prototypeConfig: config,
        }),
      ],
    },
  };
};

export function getSetterSnippet(config) {
  const { position, optType, additionalPosition } = config || {};
  let urlSetter;
  let requestParamSetter;

  if (position && optType) {
    switch (optType) {
      case 'link':
        switch (position) {
          case ButtonPosition.listItemRightButton:
            urlSetter = getListOperateRequestParamSetter(config);
            requestParamSetter = getListOperateRequestParamSetter(config);
            break;
          case ButtonPosition.tableOperate:
          case ButtonPosition.tableCell:
            urlSetter = getTableOperateUrlSetter(config);
            requestParamSetter = getTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.tableToolArea:
          case ButtonPosition.tableBatchArea:
          case ButtonPosition.tableToolAreaAfterRequestSuccess:
            urlSetter = getTableToolAreaUrlSetter(config);
            requestParamSetter = getTableToolAreaRequestParamSetter(config);
            break;
          case ButtonPosition.form:
          case ButtonPosition.formDialog:
          case ButtonPosition.filterItemEvent:
          case ButtonPosition.formItemEvent:
          case ButtonPosition.formDialogItemEvent:
          case ButtonPosition.formSubmitAfterRequestSuccess:
          case ButtonPosition.cardAction:
          case ButtonPosition.subCardAction:
          case DisplayPosition.form:
          case DisplayPosition.formDialog:
          case ButtonPosition.formItemRightButton:
            urlSetter = getFormUrlSetter(config);
            if (additionalPosition === DisplayPosition.cnArraySubAreaCard) {
              requestParamSetter =
                getArrayCardSubcardRequestParamSetter(config);
            } else {
              requestParamSetter = getFormRequestParamSetter(config);
            }
            break;
          case ButtonPosition.arrayTableOperate:
          case ButtonPosition.arrayTableCell:
            urlSetter = getArrayTableOperateUrlSetter(config);
            requestParamSetter = getArrayTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.tabEvent:
          case ButtonPosition.entryPointEvent:
          case ButtonPosition.listItemEvent:
          case ButtonPosition.statisticCardRightButton:
            urlSetter = getTabUrlSetter(config);
            requestParamSetter = getTabRequestParamSetter(config);
            break;
          case ButtonPosition.arraySubAreaCardOperate:
            requestParamSetter =
              getArrayTableItemEventRequestParamSetter(config);
            break;
          default:
            urlSetter = getStepUrlSetter(config);
            requestParamSetter = getStepRequestParamSetter(config);
            break;
        }
        break;
      case 'request':
        switch (position) {
          case ButtonPosition.tableOperate:
          case ButtonPosition.tableCell:
            requestParamSetter = getTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.tableToolArea:
          case ButtonPosition.tableBatchArea:
            requestParamSetter = getTableToolAreaRequestParamSetter2(config);
            break;
          case ButtonPosition.form:
          case ButtonPosition.formDialog:
          case ButtonPosition.cardAction:
          case ButtonPosition.subCardAction:
          case ButtonPosition.formItemEvent:
          case ButtonPosition.formDialogItemEvent:
          case ButtonPosition.filterEvent:
          case ButtonPosition.filterItemEvent:
          case ButtonPosition.formItemRightButton:
            requestParamSetter = getFormRequestParamSetter(config);
            break;
          case ButtonPosition.arrayTableOperate:
            requestParamSetter = getArrayTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.cnArrayTableItemEvent:
          case ButtonPosition.arraySubAreaCardOperate:
          case ButtonPosition.cnArraySubAreaCardItemEvent:
            requestParamSetter =
              getArrayTableItemEventRequestParamSetter(config);
            break;
          case ButtonPosition.dialog:
          case ButtonPosition.step:
          case ButtonPosition.treeNode:
          case ButtonPosition.result:
          case ButtonPosition.stepEvent:
          case ButtonPosition.tabEvent:
          case ButtonPosition.pageDidMount:
          case ButtonPosition.blockButton:
            requestParamSetter = getStepRequestParamSetter(config);
            break;
          case ButtonPosition.treeEvent:
            requestParamSetter = getTreeEventRequestParamSetter(config);
            break;
        }
        break;
      case 'batch':
        requestParamSetter = getTableToolAreaRequestParamSetter(config);
        break;
      case 'submit':
        switch (position) {
          case ButtonPosition.form:
          case ButtonPosition.cardAction:
            requestParamSetter = getFormRequestParamSetter(config);
            break;
          case ButtonPosition.formDialog:
            requestParamSetter = getFormDialogRequestParamSetter(config);
            break;
        }
        break;
      case 'download':
        switch (position) {
          case ButtonPosition.cardAction:
          case ButtonPosition.subCardAction:
            requestParamSetter = getFormRequestParamSetter(config);
            break;
          case ButtonPosition.tableBatchArea:
            requestParamSetter = getTableToolAreaRequestParamSetter3(config);
            break;
        }
        break;
      case 'export':
        switch (position) {
          case ButtonPosition.tableOperate:
            requestParamSetter = getTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.tableBatchArea:
          case ButtonPosition.tableToolArea:
            requestParamSetter = getTableToolAreaRequestParamSetter2(config);
            break;
        }
        break;
    }
  }
  return {
    urlSetter,
    requestParamSetter,
  };
}

export function getStaticDataSourceSnippet(config) {
  const { extraArraySetterItems = [], jsExpressionSetter } = config || {};
  const realJsExpressionSetter =
    jsExpressionSetter ||
    getJSExpressionPrototype({
      type: 'select',
      offlineTip: '动态控制数据推荐使用「JS代码编辑」设置该属性',
    });
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        {
          componentName: 'ArraySetter',
          title: '设置静态数据',
          props: {
            mode: 'list',
            itemSetter: {
              componentName: 'ObjectSetter',
              initialValue: {
                label: '名称',
                value: 'jack',
              },
              props: {
                config: {
                  items: [
                    {
                      name: 'label',
                      display: 'inline',
                      title: '标签',
                      isRequired: true,
                      setter: 'CnI18nSetter',
                    },
                    {
                      name: 'value',
                      display: 'inline',
                      title: '值',
                      isRequired: true,
                      setter: {
                        componentName: 'MixedSetter',
                        props: {
                          setters: [
                            {
                              componentName: 'StringSetter',
                              title: '字符串',
                            },
                            {
                              componentName: 'NumberSetter',
                              title: '数字',
                            },
                            {
                              componentName: 'BoolSetter',
                              title: '布尔（true/false）',
                            },
                          ],
                        },
                      },
                    },
                    ...extraArraySetterItems,
                  ],
                },
              },
            },
          },
        },
        {
          componentName: 'JsonSetter',
          title: 'JSON编辑器',
        },
        {
          componentName: 'ParamSelectSetter',
          props: {
            dataKey: 'aa',
            labelKey: 'aa',
            valueKey: 'aa',
            groupName: '参数列表',
          },
          title: '从数据源选择',
        },
        {
          componentName: (
            <ActionSetter
              defaultCode={`/**
 * getStaticDataSource
 */
function getStaticDataSource() {
  // 需要返回数组，格式如下
  return [
    {
      label: '选项一',
      value: 'first'
    }
  ];
}`}
              defaultActionName='getStaticDataSource'
            />
          ),
          title: 'JS代码编辑',
        },
        realJsExpressionSetter,
        {
          componentName:'VariableSetter',
        }
      ],
    },
  };
}

export function getSelectDialogSnippet(config) {
  return {
    title: '关联弹窗',
    name: '_bindDialog',
    description: '选择将要打开的弹窗',
    setter(prop) {
      // // 兼容Vision低版本
      // const nodeDocument =  this.getNode().document || this.getNode().page;
      // const NodeCache = nodeDocument.getRootNodeVisitor(
      //   'NodeCache',
      // );
      // const { nodeList } = NodeCache
      // const options = nodeList
      //   .filter(x => {
      //     // 新方案：props 里的 isTable 来标记是否是表格类型，需要做联动
      //     return x.getPropValue('isCnDialog');
      //   })
      //   .map(x => {
      //     let id = x.id || '';
      //     let title = id;
      //     if(title.slice(0,4) === 'node'){
      //       title = title.replace('node','对话框')
      //     }
      //     return {
      //       title,
      //       value: id,
      //     }
      //   });

      const options = [];
      prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
        if (item.getPropValue('isCnDialog')) {
          const isCnFormDialog = item.getPropValue('isCnFormDialog');
          const id = item.id || '';
          // 二次确认
          const current = prop.getNode?.()?.document?.getNode?.(id);
          if (current) {
            const title = getDialogTitle(current);
            options.push({
              title,
              value: id,
            });
          }
          // let title = id;
          // if (title.slice(0, 4) === 'node') {
          //   title = title.replace('node', '弹窗');
          // }
        }
      });

      return {
        componentName: 'CnSelectSetter',
        props: {
          options: [...options],
          hasClear: true,
          selectProps: {
            autoWidth: true,
          },
        },
      };
    },
    ...config,
  };
}

export function getJSXTemplate(config) {
  if (config) {
    const { position } = config || {};
    const temp = {
      componentName: 'CnJSXSetter',
      props: {
        usePopup: true,
        enableFullscreen: true,
        theme: 'vs',
      },
      title: 'React JSX代码',
    };
    if (
      [ButtonPosition.tableToolArea, ButtonPosition.tableBatchArea].includes(
        position,
      )
    ) {
      temp.initialValue = {
        type: 'js',
        source:
          'function content(formValue, state, selectedRowKeys, selectedRowRecords) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(formValue, state, selectedRowKeys, selectedRowRecords) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if (
      [ButtonPosition.formDialog, ButtonPosition.form].includes(position)
    ) {
      temp.initialValue = {
        type: 'js',
        source:
          'function content(formValue, state) { \n  // formValue: 当前表单的所有数据\n  // state: 全部组件的数据\n \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(formValue, state) {\n // formValue: 当前表单的所有数据\n  // state: 全部组件的数据\n \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if (
      [
        ButtonPosition.dialog,
        ButtonPosition.result,
        ButtonPosition.step,
        ButtonPosition.pageRightButton,
        DisplayPosition.detailInfoDescriptionRender,
      ].includes(position)
    ) {
      temp.initialValue = {
        type: 'js',
        source: 'function content(arg, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(arg, state) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([DisplayPosition.tableTopSlot].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source:
          'function content(selectedRowKeys, selectedRowRecords, dataSource, tableInfo, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(selectedRowKeys, selectedRowRecords, dataSource, tableInfo, state) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([DisplayPosition.arrayTableSummary].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source: 'function summary(dataSource, Summary, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function summary(dataSource, Summary, state) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([DisplayPosition.tabItem].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source: 'function content(currentItem, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(currentItem, state) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([DisplayPosition.tableCell].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source:
          'function content(value, index, record) { \n return {value} \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(value, index, record) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([ButtonPosition.cardAction].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source:
          'function content(formValue, state) { \n  // formValue: 当前表单的所有数据\n  // state: 全部组件的数据\n \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(formValue, state) {\n // formValue: 当前表单的所有数据\n  // state: 全部组件的数据\n \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if (
      [
        DisplayPosition.listItemContentRender,
        DisplayPosition.listItemDescriptionRender,
      ].includes(position)
    ) {
      temp.initialValue = {
        type: 'js',
        source:
          'function itemContentRender(record, index, state) { \n  return null; \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function itemContentRender(record, index, state) {\n  return null; \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    }
    return temp;
  }
}

export function getRequestWhenFocusSetterSnippet() {
  return {
    name: 'requestWhenFocus',
    title: '获得焦点时重新发请求',
    display: 'inline',
    defaultValue: true,
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: getCommonBoolDataSource(),
      },
    },
  };
}

export function getFormStateSetterSnippet(config) {
  const { title, children, extraConfig = {} } = config || {};
  const ds = getOpenDialogModeEnum({});
  return {
    groupExprName: __extraParam__,
    handleCustomGroup: () => {
      return {
        label: title || formDialogStateLabel,
        children: children || [
          {
            label: openDialogModeLabel,
            value: `${__extraParam__}.openDialogMode`,
          },
        ],
      };
    },
    renderTypeDom: () => {
      return null;
    },
    renderValueDom: (props) => {
      const { value, onChange } = props || {};
      return (
        <Select
          size={'small'}
          hasClear
          value={value?.value}
          dataSource={ds}
          onChange={(v) => {
            onChange?.(value, {
              value: v,
            });
          }}
        />
      );
    },
    ...extraConfig,
  };
}

export function getDataOriginSetterSnippet(config = {}) {
  return {
    name: 'dataOrigin',
    title: '数据来源',
    display: 'block',
    initialValue: 'static',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          { title: '远程请求', value: 'request' },
          { title: '静态数据', value: 'static' },
        ],
      },
    },
    ...config,
  };
}

export function getDateTypeSetterSnippet(config = {}) {
  return {
    name: 'type',
    title: '类型',
    display: 'inline',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          { title: '日期', value: 'date', tip: '日期选择器' },
          { title: '周', value: 'week', tip: '周选择器' },
          { title: '月', value: 'month', tip: '月选择器' },
          { title: '年', value: 'year', tip: '年选择器' },
        ],
      },
    },
    ...config,
  };
}

export function getTableCellClickSetterSnippet(config) {
  const { buttonPosition } = config || {};
  return {
    componentName: 'ObjectSetter',
    props: {
      config: {
        items: [
          {
            name: 'optType',
            title: '按钮功能',
            display: 'inline',
            setter: {
              componentName: 'CnSelectSetter',
              props: {
                selectProps: {
                  hasClear: true,
                },
                options: getButtonListByPosition(buttonPosition),
              },
            },
          },
          {
            name: 'options',
            display: 'plain',
            title: '按钮配置项',
            setter: {
              componentName: 'ObjectSetter',
              props: {
                config: {
                  items: [...getButtonPrototypeListByPosition(buttonPosition)],
                },
              },
            },
          },
        ],
      },
    },
  };
}

export function getRequestConfigSetterSnippet(config, extraConfig) {
  const { extraServiceProps, position } = extraConfig || {};
  let extraConfigSetter;
  const requestExecuteSetter = getRequestExecuteSetter({
    exprSetter: getExprSetterSnippet({
      position,
      ignoreArrayTableCurrentRow: true,
    }),
  });
  if (requestExecuteSetter) {
    extraConfigSetter = [requestExecuteSetter];
  }
  return {
    name: 'requestConfig',
    title: '查询服务',
    display: 'inline',
    setter: {
      componentName: 'ServiceChoiceSetter',
      props: {
        mockDataTemplate: {
          success: true,
          data: [
            {
              label: '选项一',
              value: 'first',
              children: [
                {
                  label: '子选项一',
                  value: 'sub1',
                },
              ],
            },
            {
              label: '选项二',
              value: 'second',
            },
          ],
        },
        paramTitleDom: <div className=''>请求参数配置：</div>,
        responseDom: (
          <div style={{ paddingTop: '10px' }}>
            请求返回结果的数据结构：
            <a
              target={'_blank'}
              href='https://yuque.antfin.com/cn-framework-committee/cn-ui-data-structure/cn-async-select#iEuF0'
              rel='noreferrer'
            >
              接口文档
            </a>{' '}
            <CnTooltip v2 align={'t'} trigger={<a>接口预览</a>}>
              <div style={{ width: '200px', height: '260px' }}>
                <img
                  style={{ width: '100%' }}
                  src='https://img.alicdn.com/imgextra/i1/O1CN01W5SNFR25Fg4QyRC53_!!6000000007497-0-tps-456-570.jpg'
                />
              </div>
            </CnTooltip>
          </div>
        ),
        buttonText: '选择请求API',
        params: {
          env: 'pre',
          pageSize: 999,
          // serviceType: 'HSF',
        },
        extraConfigSetter,
        paramSetter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'ParamSelectSetter',
                props: {
                  dataKey: 'config',
                  labelKey: 'label',
                  valueKey: 'name',
                  groupName: '参数列表',
                },
                title: '选择参数',
              },
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              getJSExpressionPrototype({ type: 'formRequest' }),
            ],
          },
        },
        resultProcessFuncTemplate: `function(res) {
  // 需要返回的如下的数据结构
  // return {
  //   success: true,
  //   data: [
  //     {
  //        label:"xx",
  //        value:"xx",
  //     }
  //   ]
  // }
 return res;
}`,
        ...extraServiceProps,
      },
    },
    ...config,
  };
}

export function getColsSetterSnippet(config) {
  return {
    name: 'cols',
    title: '一行几列',
    display: 'inline',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          { title: '自适应', value: undefined },
          { title: '1', value: 1 },
          { title: '2', value: 2 },
          { title: '3', value: 3 },
          { title: '4', value: 4 },
          { title: '5', value: 5 },
          { title: '6', value: 6 },
        ],
      },
    },
    ...config,
  };
}

export function getStepShapeSetterSnippet() {
  return {
    title: '样式',
    name: 'shape',
    defaultValue: 'circle',
    setter: {
      componentName: 'SelectSetter',
      props: {
        options: [
          {
            label: '圆形（circle）',
            value: 'circle',
          },
          {
            label: '箭头（arrow）',
            value: 'arrow',
          },
          {
            label: '点（dot）',
            value: 'dot',
          },
        ],
      },
    },
  };
}

export function getFormHandleTypeSetterSnippet(config) {
  const {
    componentTitle = '表单',
    componentName = 'Form',
    handleTypeName,
  } = config || {};
  return {
    title: `对${componentTitle}数据做何处理`,
    name: handleTypeName || 'handleType',
    setter: {
      componentName: 'CnSelectSetter',
      props: {
        selectProps: {
          hasClear: true,
        },
        options: [
          {
            label: `给${componentTitle}每个字段设置数据`,
            value: `set${componentName}FieldValue`,
          },
          {
            label: `清空${componentTitle}的数据`,
            value: `clear${componentName}Value`,
          },
          {
            label: `给整个${componentTitle}设置数据`,
            value: `setAll${componentName}Value`,
          },
        ],
      },
    },
  };
}

export function getRequestExecuteSetter(config) {
  const { exprSetter } = config || {};
  if (isArrayNotEmpty(exprSetter)) {
    return {
      name: 'execute',
      display: 'inline',
      title: '请求是否执行',
      setter: {
        componentName: 'MixedSetter',
        props: {
          setters: [
            ...exprSetter,
            {
              title: '布尔 (true/false)',
              componentName: 'RadioGroupSetter',
              props: {
                options: [
                  { value: true, title: '执行' },
                  { value: false, title: '不执行' },
                ],
              },
            },
          ],
        },
      },
    };
  }
}

export function getExprSetterSnippet(config) {
  const { position, ignoreArrayTableCurrentRow } = config || {};
  let configList = [];
  let jsExpressionPrototype;
  if (
    [
      DisplayPosition.form,
      DisplayPosition.filter,
      DisplayPosition.formDialog,
    ].includes(position)
  ) {
    configList = [
      {
        dataKey: 'config',
        labelKey: 'label',
        valueKey: 'name',
        groupName: '当前表单字段',
        groupExprName: getFormExprNameByPosition({ position }),
        needSecondParam: false,
      },
      {
        groupName: '其他数据',
        groupExprName: __dataSource__,
        needSecondParam: true,
      },
    ];
    jsExpressionPrototype = getJSExpressionPrototype({ type: 'form' });
    return [
      {
        componentName: <ExprSetter configList={configList} />,
        title: '简单表达式',
      },
      jsExpressionPrototype,
    ];
  } else if ([DisplayPosition.cnArrayTable].includes(position)) {
    configList = [
      {
        dataKey: 'config',
        labelKey: 'label',
        valueKey: 'name',
        groupName: '当前表单字段',
        groupExprName: getFormExprNameByPosition({ position }),
        needSecondParam: false,
      },
      {
        groupName: '其他数据',
        groupExprName: __dataSource__,
        needSecondParam: true,
      },
    ];
    if (ignoreArrayTableCurrentRow === true) {
    } else {
      configList.unshift({
        dataKey: 'arrayTable',
        labelKey: 'label',
        valueKey: 'name',
        groupName: '表格当前行数据',
        groupExprName: __arrayTableCurrentRow__,
        needSecondParam: false,
      });
    }
    jsExpressionPrototype = getJSExpressionPrototype({
      type: 'arrayTableCurrentRow',
    });
    return [
      {
        componentName: <ExprSetter configList={configList} />,
        title: '简单表达式',
      },
      jsExpressionPrototype,
    ];
  } else if (position === 'formDefaultValue') {
    configList = [
      {
        groupName: '其他数据',
        groupExprName: __dataSource__,
        needSecondParam: true,
      },
    ];
    jsExpressionPrototype = getJSExpressionPrototype({ type: 'base' });
    return [
      {
        componentName: <ExprSetter configList={configList} />,
        title: '简单表达式',
      },
      jsExpressionPrototype,
    ];
  }
}

export function getSelectTableSnippet(config) {
  return createTableSelectSetters({}, config)[0];
}

export function getSelectFilterSnippet(config, extraConfig) {
  return createFilterSelectSetters(config, extraConfig)[0];
}

export function getNodeIdSetterSnippet() {
  return {
    name: '_nodeId',
    title: '节点 ID',
    display: 'inline',
    initialValue() {
      return this.getNode().id;
    },
    setter: <IdSetter />,
  };
}

export function getTableRemoteSnippet(config) {
  const { needMockRequestInTable = true, paramSelectSetter } = config || {};
  return {
    componentName: 'ServiceChoiceSetter',
    props: {
      paramTitleDom: (
        <div>
          请求参数配置{' '}
          <span
            style={{ fontWeight: 'bold', color: 'red', marginLeft: '30px' }}
          >
            提示：表格请求时会默认带上筛选栏的数据作为参数，无需手动配置！
          </span>
        </div>
      ),
      responseDom: (
        <div style={{ paddingTop: '10px' }}>
          请求返回结果的数据结构：
          <a
            target={'_blank'}
            href='https://yuque.antfin.com/cn-framework-committee/cn-ui-data-structure/cn-table#YHipc'
            rel='noreferrer'
          >
            接口文档
          </a>{' '}
          <CnTooltip v2 align={'t'} trigger={<a>接口预览</a>}>
            <div style={{ width: '200px', height: '340px' }}>
              <img
                style={{ width: '100%' }}
                src='https://img.alicdn.com/imgextra/i3/O1CN01cjQiJp1EE99hRXt2d_!!6000000000319-0-tps-638-1090.jpg'
              />
            </div>
          </CnTooltip>
        </div>
      ),
      mockDataTemplate: {
        success: true,
        data: {
          tableData: [
            {
              name: 'aa',
              age: 18,
            },
          ],
          paging: {
            currentPage: 1,
            pageSize: 10,
            totalCount: 1,
          },
        },
      },
      buttonText: '选择请求API',
      params: {
        env: 'pre',
        pageSize: 999,
        // serviceType: 'HSF',
      },
      resultProcessFuncTemplate: `function(res) {
  // 需要返回的如下的数据结构
  // return {
  //   success: true,
  //   data: {
  //     tableColumns: [{title:"xx",dataIndex:"xx"}],
  //     tableData: [],
  //     paging: {
  //       currentPage: 1,
  //       pageSize: 20,
  //       totalCount: 99,
  //     }
  //   }
  // }
 return res;
}`,
      needMockRequestInTable,
      paramSetter: paramSelectSetter || [
        getParamSetterPrototype({ type: 'filterWithPagination' }),
        {
          componentName: 'StringSetter',
          title: '字符串',
        },
        getJSExpressionPrototype({ type: 'tableInitRequest' }),
      ],
      // getExtraServiceDom:(setterContext)=>{
      //   return <CnTabItem
      //     title='DataEasy数据服务'
      //     key='tiangong'
      //   >
      //     <div className='scc-tab-content'>
      //       <div
      //         className={'cn-sc-setter-config-wrap'}
      //         style={{ display: 'flex' }}
      //       >
      //         <div className='service-api-list'>
      //           <a
      //             target={'_blank'}
      //             style={{float:'right'}}
      //             href="https://tg.cainiao.test/market/index.htm">DataEasy数据服务市场</a>
      //           <div className='label'>接口列表：</div>
      //           <CnAsyncSelect
      //             className='select-list'
      //             placeholder='请选择天工数据源'
      //             hasClear
      //             showSearch
      //             filterLocal={false}
      //             requestConfig={{
      //               // url:'https://mocks.alibaba-inc.com/mock/conelowcode/queryDataSetByPage',
      //               url:'https://cn-x-gateway.cainiao.test/cone/buc-for-l4/queryDataSetByPage',
      //               withCredentials: true,
      //               searchFormat:(originalParam)=>{
      //                 return {
      //                   currentPage:1,
      //                   pageSize:20,
      //                   keyWord:originalParam?.key,
      //                 };
      //               },
      //               formatResult:(res)=>{
      //                 let result = [];
      //                 const tempData = res?.data?.tableData
      //                 if(isArrayNotEmpty(tempData)) {
      //                   result = tempData.map(item=>{
      //                     return {
      //                       label: item?.name || item?.guid,
      //                       value: item?.guid,
      //                     }
      //                   })
      //                 }
      //                 return result;
      //               }
      //             }}
      //             value={setterContext?.state?.selectedTianGongDs}
      //             style={{ width: '100%' }}
      //             onChange={(v, m ,record)=>{
      //               setterContext.setState({
      //                 selectedTianGongDs: v
      //               })
      //             }
      //             }
      //           />
      //         </div>
      //       </div>
      //     </div>
      //   </CnTabItem>
      // },
    },
  };
}

export const getCnFormStepConfigSnippet = () => {
  return [
    {
      name: 'cnFormStepConfig',
      title: '分步表单配置',
      display: 'accordion',
      collapsed: true,
      setter: {
        componentName: 'ObjectSetter',
        props: {
          config: {
            items: [
              {
                name: 'current',
                title: '当前步骤',
                display: 'inline',
                setter: {
                  componentName: 'MixedSetter',
                  props: {
                    setters: [
                      {
                        componentName: 'NumberSetter',
                        title: '第几步',
                      },
                      getJSExpressionPrototype({ type: 'base' }),
                    ],
                  },
                },
              },
            ],
          },
        },
      },
    },
    ...createEventSetters({
      position: ButtonPosition.formEvent,
      initialValue: {
        // optType: 'setFormStepCurrent'
      },
      title: '配置表单的回调',
    }),
  ];
};

export function getLabelAlignSetterSnippet() {
  return {
    name: 'labelAlign',
    title: '标签位置',
    display: 'inline',
    // defaultValue: 'top',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          { title: '自动', value: 'auto' },
          { title: '输入框上方', value: 'top' },
          { title: '输入框左侧', value: 'left' },
        ],
      },
    },
  };
}

export function getFieldSelectSetterSnippet() {
  return {
    name: 'label',
    display: 'inline',
    title: '选择字段',
    isRequired: true,
    setter: {
      componentName: 'CnTreeSelectSetter',
      props: (field) => {
        const dataSource = [];
        const currentData = field?.parent?.parent?.parent?.getValue?.();
        const { _bindForm } = currentData || {};
        if (_bindForm && field) {
          const node = getNodeById({
            field,
            id: _bindForm,
          });
          if (node?.id) {
            const config = node?.getPropValue?.('config');
            if (isArrayNotEmpty(config)) {
              config.forEach((item) => {
                if (item?.name) {
                  let tempLabel = handleI18nLabel(item?.label) || item.name;
                  if (typeof tempLabel !== 'string') {
                    tempLabel = item.name;
                  }
                  const temp = {
                    label: tempLabel,
                    value: item.name,
                  };
                  dataSource.push(temp);
                  if (isRecursionComponent(item?.componentName)) {
                    const children = getArrayTableFieldList({
                      config: item?.options?.config,
                      arrayTableName: item.name,
                    });
                    if (isArrayNotEmpty(children)) {
                      temp.children = children;
                    }
                  }
                }
              });
            }
          }
        }
        return {
          dataSource,
          popupClassName: 'cn-tree-select-setter-pupup',
        };
      },
    },
  };
}

export function getCnSelectSetterSnippet(config) {
  const { propsConfig, options } = config || {};
  return {
    componentName: 'CnSelectSetter',
    props: {
      options,
      selectProps: {
        hasClear: true,
      },
      ...propsConfig,
    },
  };
}

export function getObjectSetterSnippet(config) {
  const { items } = config || {};
  return {
    componentName: 'ObjectSetter',
    props: {
      config: {
        items,
      },
    },
  };
}

export function getMixedSetterSnippet(config) {
  const { setters } = config || {};
  return {
    componentName: 'MixedSetter',
    props: {
      setters,
    },
  };
}

export function getRightButtonSetterSnippet() {
  return {
    name: 'rightButtons',
    title: '配置字段的右侧按钮',
    display: 'accordion',
    collapsed: true,
    extraProps: {
      defaultCollapsed: true,
    },
    className: 'cn-array-setter-validator',
    setter: createButtonListSetters({
      position: ButtonPosition.formItemRightButton,
    }),
  };
}

export function getArraySetterSnippet(config) {
  const { initialValue, configure } = config || {};
  return {
    componentName: 'ArraySetter',
    props: {
      mode: 'list',
      itemSetter: {
        componentName: 'ObjectSetter',
        initialValue,
        props: {
          config: {
            items: configure,
          },
        },
      },
    },
  };
}

// 生成可编辑字段的配置项
export function getArrayTableCurrentRowFieldSnippet() {
  return {
    groupName: '当前行数据',
    groupExprName: __arrayTableCurrentRow__,
    handleCustomGroup: (extra, field) => {
      const path = field?.path;
      if (
        Array.isArray(path) &&
        path.length > 5 &&
        path[0] === 'config' &&
        path[2] === 'options' &&
        (path[3] === 'config' || path[3] === 'buttons')
      ) {
        const arrayTableIndex = path[1];
        if (typeof arrayTableIndex === 'number') {
          const formConfig = field?.getNode?.()?.getPropValue?.('config');
          const arrayTableConfig = formConfig?.[arrayTableIndex] || {};
          if (
            isRecursionComponent(arrayTableConfig?.componentName) &&
            arrayTableConfig?.options?.config?.length > 0
          ) {
            const originList = arrayTableConfig?.options?.config;
            const tempList = handleOriginList(
              originList,
              'label',
              'name',
              `${__extraParam__}.${__arrayTableCurrentRow__}`,
            );
            if (isArrayNotEmpty(tempList)) {
              extra.children = tempList;
            }
          }
        }
      }
    },
  };
}

export function getHandlePropsSetterSnippet(config) {
  return {
    name: 'handleProps',
    title: '手动设置组件props',
    display: 'inline',
    setter: getJSExpressionPrototype({
      type: 'props',
    }),
  };
}

export function getDataSetterSnippet() {
  return [
    {
      name: 'dataFrom',
      title: '数据来源',
      setter: getObjectSetterSnippet({
        items: [
          getDataOriginSetterSnippet({
            defaultValue: dataOriginStatic,
            display: 'plain',
          }),
          getRequestConfigSetterSnippet({
            condition: (prop) => {
              return (
                prop?.parent?.getPropValue?.('dataOrigin') === dataOriginRequest
              );
            },
          }),
          {
            name: 'dataSource',
            title: '编辑静态数据',
            display: 'plain',
            setter: getStaticDataSourceSnippet(),
            condition: (prop) => {
              return (
                prop?.parent?.getPropValue?.('dataOrigin') === dataOriginStatic
              );
            },
          },
        ],
      }),
    },
  ];
}

export function getCnSelectSetter(config) {
  const { options } = config || {};
  return {
    componentName: 'CnSelectSetter',
    props: {
      options,
      selectProps: {
        hasClear: true,
      },
    },
  };
}
