import React from 'react';
import {
  getJSExpressionPrototype,
  getParamSetterPrototype,
} from '@/common/manager/common-style';
import {
  generateDataSource,
  getDsNameFromVariable,
  handleComponentTitle,
  handleI18nLabel,
  isArrayNotEmpty,
} from '@/common/util/util';
import {
  __arrayTableCurrentRow__,
  __dataSource__,
  __extraParam__,
  formDialogStateLabel,
  getCommonBoolDataSource,
  getFormExprNameByPosition,
  getOpenDialogModeEnum,
  openDialogModeLabel,
} from '@/common/util/expr-const';
import {
  dataOriginRequest,
  dataOriginStatic,
} from '@/common/util/const';
import {
  getButtonListByPosition,
  getButtonPrototypeListByPosition,
} from '@/common/manager/button';
import { ButtonPosition } from '@/type/button-position';
import DataSourceSetter from '@/common/setter/datasource-setter/datasource-setter';
import ExprSetter from '@/common/setter/expr-setter';
import { DisplayPosition } from '@/type/display-position';
import IdSetter from '@/common/setter/id-setter';
import { ParamSelectSetter } from '@/common/setter/param-select-setter';

const { Select, CnTooltip } = window.CNUI || {};

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',
        }),
      ],
    },
  };
};

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' }),
        getJSExpressionPrototype({
          type: 'formRequest',
        }),
      ],
    },
  };
};

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

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

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

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


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

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',
        }),
      ],
    },
  };
};

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 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',
        }),
      ],
    },
  };
};

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

  if (position && optType) {
    switch (optType) {
      case 'link':
      case 'jsbridge': // jsbridge 跟url可以用同一个
        switch (position) {
          case ButtonPosition.cnCardItemsSubAction:
          case ButtonPosition.tableOperate:
          case ButtonPosition.tableCell:
          case ButtonPosition.normalCardSubAction:
          case ButtonPosition.normalCardAction:
            urlSetter = getTableOperateUrlSetter(config);
            requestParamSetter = getTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.tableToolArea:
          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:
            urlSetter = getFormUrlSetter(config);
            requestParamSetter = getFormRequestParamSetter(config);
            break;
          case ButtonPosition.arrayTableOperate:
          case ButtonPosition.arrayTableCell:
            urlSetter = getArrayTableOperateUrlSetter(config);
            requestParamSetter = getArrayTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.step:
          case ButtonPosition.dialog:
          case ButtonPosition.pageDidMount:
          case ButtonPosition.navBarEvent:
          case ButtonPosition.navBarRightButton:
          case ButtonPosition.normalCardSubAction:
          case ButtonPosition.normalCardAction:
          case ButtonPosition.result:
            urlSetter = getStepUrlSetter(config);
            requestParamSetter = getStepRequestParamSetter(config);
            break;
          case ButtonPosition.tabEvent:
            urlSetter = getTabUrlSetter(config);
            requestParamSetter = getTabRequestParamSetter(config);
            break;
          case ButtonPosition.entryPointsItemClick:
            urlSetter = getQuickEntryItemClickUrlSetter(config);
            requestParamSetter = getQuickEntryItemClickRequestSetter(config);
            break;
          case ButtonPosition.listItemClick:
            urlSetter = getListItemClickUrlSetter(config);
            requestParamSetter = getListItemClickRequestSetter(config);
            break;
          default:
            urlSetter = getStepUrlSetter(config);
            requestParamSetter = getStepRequestParamSetter(config);
            break;
        }
        break;
      case 'request':
        switch (position) {
          case ButtonPosition.cnCardItemsSubAction:
          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:
            requestParamSetter = getFormRequestParamSetter(config);
            break;
          case ButtonPosition.arrayTableOperate:
            requestParamSetter = getArrayTableOperateRequestParamSetter(config);
            break;
          case ButtonPosition.cnArrayTableItemEvent:
            requestParamSetter =
              getArrayTableItemEventRequestParamSetter(config);
            break;
          case ButtonPosition.dialog:
          case ButtonPosition.step:
            requestParamSetter = getStepRequestParamSetter(config);
            break;
          case ButtonPosition.entryPointsItemClick:
            requestParamSetter = getQuickEntryItemClickRequestSetter(config);
            break;
        }
        break;
      case 'batch':
        requestParamSetter = getTableToolAreaRequestParamSetter(config);
        break;
      case 'submit':
        switch (position) {
          case ButtonPosition.form:
            requestParamSetter = getFormRequestParamSetter(config);
            break;
          case ButtonPosition.formDialog:
            requestParamSetter = getFormDialogRequestParamSetter(config);
            break;
        }
        break;
      case 'download':
        switch (position) {
          case ButtonPosition.tableBatchArea:
            requestParamSetter = getTableToolAreaRequestParamSetter2(config);
            break;
          case ButtonPosition.cardAction:
          case ButtonPosition.subCardAction:
            requestParamSetter = getFormRequestParamSetter(config);
            break;
        }
        break;
    }
  }
  return {
    urlSetter,
    requestParamSetter,
  };
}

export function getStaticDataSourceSnippet() {
  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）',
                            },
                          ],
                        },
                      },
                    },
                  ],
                },
              },
            },
          },
        },
        {
          componentName: 'ParamSelectSetter',
          props: {
            dataKey: 'aa',
            labelKey: 'aa',
            valueKey: 'aa',
            groupName: '参数列表',
          },
          title: '从数据源选择',
        },
        getJSExpressionPrototype({ type: 'select' }),
        {
          componentName: 'JsonSetter',
          title: 'JSON编辑器',
        },
      ],
    },
  };
}

export function getSelectDialogSnippet() {
  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) {
            let title = '弹窗';
            if (isCnFormDialog) {
              title = '表单弹窗';
            }
            const dialogTitle = handleI18nLabel(item?.propsData?.title || '');
            if (dialogTitle) {
              title += `_${handleComponentTitle(dialogTitle)}`;
            } else {
              title += `_${id}`;
            }
            options.push({
              title,
              value: id,
            });
          }
          // let title = id;
          // if (title.slice(0, 4) === 'node') {
          //   title = title.replace('node', '弹窗');
          // }
        }
      });

      return {
        componentName: 'SelectSetter',
        props: {
          options: [...options],
          hasClear: true,
        },
      };
    },
  };
}

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.form, ButtonPosition.formDialog].includes(position)
    ) {
      temp.initialValue = {
        type: 'js',
        source: 'function content(formValue, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(formValue, state) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if (
      [ButtonPosition.dialog, ButtonPosition.result].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.stepItemContent].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source:
          'function content(currentStepInfo, currentIndex, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(currentStepInfo, 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 return value; \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 return value; \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([DisplayPosition.tabItem].includes(position)) {
      temp.initialValue = {
        type: 'js',
        source: 'function content(currentTabInfo, state) { \n  \n}',
        compiled:
          'function main(){\n    \n    "use strict";\n\nvar __compiledFunc__ = function content(currentTabInfo, state) {\n  \n};\n    return __compiledFunc__.apply(this, arguments);\n  }',
        error: {},
      };
    } else if ([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: false,
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: getCommonBoolDataSource(),
      },
    },
  };
}

export function getFormStateSetterSnippet() {
  const ds = getOpenDialogModeEnum({});
  return {
    groupExprName: __extraParam__,
    handleCustomGroup: () => {
      return {
        label: formDialogStateLabel,
        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,
            });
          }}
        />
      );
    },
  };
}

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

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 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 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 createDataSourceSetters() {
  return [
    {
      name: '_dataSource',
      title: '数据源',
      display: 'inline',
      supportVariable: false,
      mutator(value) {
        const node = this.getProps().getNode();
        const result = getDsNameFromVariable(value);
        if (result) {
          node.setPropValue('_dataSourceName', result);
        }
      },
      initialValue(value) {
        const v = this.getValue();
        const { componentName } = this;
        const currentDataSource = this.getPropValue('_dataSource');
        if (!currentDataSource && !v) {
          const ds = generateDataSource({ componentName });
          if (ds?.name) {
            this.parent?.setPropValue?.('_dataSourceName', ds.name);
            return {
              type: 'variable',
              variable: `state.${ds.name}`,
            };
          }
        }
      },
      setter: <DataSourceSetter />,
    },
    {
      name: '_dataSourceName',
      title: '数据源名称',
      display: 'none',
      // supportVariable: true,
      initialValue() {
        const value = this.parent?.getPropValue?.('_dataSourceName');
        if (!value) {
          const node = this.getNode();
          const dsExpr = node?.getPropValue('_dataSource');
          return getDsNameFromVariable(dsExpr);
        }
        return value;
      },
    },
  ];
}

export function getSelectModeSetterSnippet() {
  return {
    name: 'mode',
    title: '选择模式',
    display: 'inline',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          {
            title: '单选',
            value: 'single',
          },
          {
            title: '多选',
            value: 'multiple',
          },
        ],
      },
    },
  };
}

export function getMultipleSetterSnippet() {
  return {
    name: 'multiple',
    title: '选择模式',
    display: 'inline',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          {
            title: '单选',
            value: false,
          },
          {
            title: '多选',
            value: true,
          },
        ],
      },
    },
  };
}

export function getMaxLengthSetterSnippet() {
  return {
    name: 'maxLength',
    title: '文本最大长度',
    display: 'inline',
    setter: 'NumberSetter',
  };
}

export function getDirectionSetterSnippet() {
  return {
    name: 'direction',
    title: '选项的排列方式',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          {
            title: '水平排列',
            value: 'hoz',
          },
          {
            title: '竖直排列',
            value: 'ver',
          },
        ],
      },
    },
  };
}

export function getDatePrecisionSetterSnippet() {
  return {
    name: 'precision',
    title: '支持选择到',
    display: 'inline',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          { title: '年', value: 'year' },
          { title: '月', value: 'month' },
          { title: '日', value: 'day' },
          { title: '时', value: 'hour' },
          { title: '分', value: 'minute' },
          { title: '秒', value: 'second' },
          { title: '周', value: 'week' },
          { title: '周几', value: 'week-day' },
        ],
      },
    },
  };
}

export function getSearchRemoteSetterSnippet() {
  return {
    name: 'searchRemote',
    title: '当新输入时 重新发请求',
    display: 'inline',
    tip: '开启时，每次输入都会重新发请求获取数据',
    setter: {
      componentName: 'RadioGroupSetter',
      props: {
        options: [
          { title: '是', value: true },
          { title: '否', value: false },
          { title: '不设置' },
        ],
      },
    },
  };
}

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 createFormStyleSetters(config) {
  const { position } = config || {};
  const readOnlyConfigList = [
    {
      groupName: '其他数据',
      groupExprName: __dataSource__,
      needSecondParam: true,
    },
  ];
  if (ButtonPosition.formDialog === position) {
    readOnlyConfigList.unshift({
      groupExprName: __extraParam__,
      handleCustomGroup: () => {
        return {
          label: formDialogStateLabel,
          children: [
            {
              label: openDialogModeLabel,
              value: `${__extraParam__}.openDialogMode`,
            },
          ],
        };
      },
      renderTypeDom: () => {
        return null;
      },
      renderValueDom: (props) => {
        const { value, onChange } = props || {};
        return (
          <Select
            size={'small'}
            hasClear
            value={value?.value}
            dataSource={getOpenDialogModeEnum()}
            onChange={(v) => {
              onChange(value, {
                value: v,
              });
            }}
          />
        );
      },
    });
  }
  return [
    // getColsSetterSnippet({
    //   initialValue: 1,
    // }),
    {
      name: 'readOnly',
      title: '只读',
      display: 'inline',
      tip: '',
      // supportVariable: false,
      className: 'cn-text-expr-setter',
      setter: {
        componentName: 'MixedSetter',
        props: {
          setters: [
            {
              // componentName: 'BoolSetter',
              // title: '布尔（true/false）',
              title: '是 或 否',
              componentName: 'RadioGroupSetter',
              props: {
                options: [
                  { value: true, title: '是' },
                  { value: false, title: '否' },
                  { title: '不设置' },
                ],
              },
            },
            {
              componentName: <ExprSetter configList={readOnlyConfigList} />,
              title: '简单表达式',
            },
            getJSExpressionPrototype({ type: 'form' }),
          ],
        },
      },
    },
    getLabelAlignSetterSnippet(),
    getWrapperAlignSetterSnippet(),
    getLabelWidthSetterSnippet(),
    // {
    //   name: 'allowCopy',
    //   title: '只读时显示数据拷贝图标',
    //   display: 'inline',
    //   className: 'cn-text-expr-setter',
    //   setter: {
    //     componentName: 'MixedSetter',
    //     props: {
    //       setters: [
    //         {
    //           title: '是 或 否',
    //           componentName: 'RadioGroupSetter',
    //           props: {
    //             options: [
    //               { value: true, title: '是' },
    //               { value: false, title: '否' },
    //               { title: '不设置' },
    //             ],
    //           },
    //         },
    //       ],
    //     },
    //   },
    //   condition(prop){
    //     return prop?.getNode?.()?.getPropValue?.('formStyle.readOnly') === true;
    //   }
    // }
  ];
}

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 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 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' }),
      ],
    },
  };
}

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

export function createFormDataSourceSetters() {
  return [
    {
      title: '高级配置',
      type: 'group',
      collapsed: true,
      display: 'accordion',
      items: [getNodeIdSetterSnippet(), ...createDataSourceSetters()],
    },
  ];
}

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

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

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

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

export function createTableSelectSetters(config, extraConfig) {
  const { mode } = config || {};
  return [
    {
      name: '_bindTable',
      title: '选择表格',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          if (item.getPropValue('isCnTable')) {
            const id = item.id || '';
            const tableName = item?.propsData?.tableName || '';
            const title = `表格_${tableName}`;
            options.push({
              title,
              value: id,
            });
          }
        });
        return {
          componentName: 'SelectSetter',
          props: {
            mode: mode || 'multiple',
            // hasClear: true,
            options,
          },
        };
      },
      ...extraConfig,
    },
  ];
}

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

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


export function getLabelWidthSetterSnippet() {
  return {
    name: 'labelWidth',
    title: '标签宽度',
    display: 'inline',
    setter: 'NumberSetter',
  }
}

export function getWrapperAlignSetterSnippet() {
  return {
    name: 'wrapperAlign',
    title: '内容对齐方向',
    display: 'inline',
    setter: {
      componentName: 'MixedSetter',
      props: {
        setters: [
          {
            componentName: 'RadioGroupSetter',
            props: {
              options: [
                { title: '左对齐', value: 'left' },
                { title: '右对齐', value: 'right' },
              ],
            },
          },
        ],
      },
    },
  };
}

export function createFilterSelectSetters(config, extraConfig) {
  const { mode } = config || {};
  return [
    {
      name: '_bindFilter',
      title: '选择筛选栏',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          if (item.getPropValue('isCnFilter')) {
            const prefix = '筛选栏';
            const id = item.id || '';
            const title = `${prefix}_${
              handleI18nLabel(item?.propsData?.title) || ''
            }`;
            options.push({
              title,
              value: id,
            });
          }
        });
        return {
          componentName: 'SelectSetter',
          props: {
            mode,
            // hasClear: true,
            options,
          },
        };
      },
      ...extraConfig,
    },
  ];
}

export function getStepRequestConfigSetterSnippet(config) {
  return {
    name: 'requestConfig',
    title: '查询服务',
    display: 'inline',
    // className:'cn-inline-setter-reduce',
    setter: {
      componentName: 'ServiceChoiceSetter',
      props: {
        buttonText: '选择请求API',
        params: {
          env: 'pre',
          pageSize: 999,
          // serviceType: 'HSF',
        },
        paramSetter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'ParamSelectSetter',
                props: {
                  dataKey: 'aa',
                  labelKey: 'aa',
                  valueKey: 'aa',
                  groupName: '参数列表',
                },
                title: '选择参数',
              },
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
            ],
          },
        },
      },
    },
    ...config,
  };
}


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 getSelectTableSnippet(config) {
  return createTableSelectSetters({}, config)[0];
}

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