import React, {
  useCallback,
  useEffect,
  useState,
  useRef,
  forwardRef,
  useImperativeHandle,
} from 'react';
import {
  // CnCard,
  CnForm as UICnForm,
  // CnFormField,
  CnFormProps,
  CnBox,
  CnButton,
  formilyCore,
  CnAgreement,
  CnFormField,
  formilyReact,
  FormConsumer,
} from '@cainiaofe/cn-ui-m';
import { toJS } from '@formily/reactive';
import isPlainObject from 'lodash/isPlainObject';
import isEmpty from 'lodash/isEmpty';
import {
  calculateTextExprValue,
  calculateWaitComponentList,
  executeObjectExpr,
  getFormDefaultValue,
  getRealizeValue,
  getRealResponse,
  getRunTimeItem,
  isArrayNotEmpty,
  isDesignMode,
  isRecursionComponent,
  makeFormItemSchema,
  transProxyToObject,
} from '@/common/util/util';
import {
  componentMap,
  getFormExtraComponents,
} from '@/common/manager/filter-item';
import cloneDeep from 'lodash/cloneDeep';
import cloneDeepWith from 'lodash/cloneDeepWith';
import { getButtonAction } from '@/common/manager/button';
import { ButtonPosition } from '@/type/button-position';
import isEqualWith from 'lodash/isEqualWith';
import {
  __arrayTableCurrentRow__,
  __dataSource__,
  __extraParam__,
  __filterValue__,
  __formValue__,
  __stateValueOfSplit__,
} from '@/common/util/expr-const';
import get from 'lodash/get';
import { columnSuffix, dataOriginStatic } from '@/common/util/const';
import { makeRequest } from '@/common/manager/request';
import { _getFormValues } from '@/common/util/biz-component-prop-name';

const { Observer } = formilyReact || {};
// import { withI18n } from 'panda-i18n';
// import locale from '@/locale';

const CnAgreementView = (props) => {
  return <CnAgreement {...props} checked={props?.value} />;
};

const {
  createForm,
  onFormValuesChange,
  onFieldValueChange,
  onFieldReact,
  onFieldInputValueChange,
  onFieldChange,
} = formilyCore || {};

// !!! 注意 ViewProps 会被 ../index 使用
export declare interface FormProps extends CnFormProps {
  /**
   * 样式类名
   */
  className?: string;
  /**
   * 表单项配置
   */
  config?: Array<{
    componentName: string;
    options: Record<string, any>;
    [key: string]: any;
  }>;
}

const CnCard = 'CnCard';
const CnCardSubCard = 'CnCardSubCard';
const CnFormStepItem = 'CnFormStepItem';
const CnFormGrid = 'CnFormGrid';

function View(props: FormProps, ref): JSX.Element {
  const {
    children,
    config,
    _context,
    submitProps,
    resetProps,
    hasFooterSubmit,
    buttons,
    _dataSourceName,
    formStyle,
    defaultParams,
    dynamicConfig,
    formInstance: parentFormInstance,
    _dataSource,
    onCreateForm,
    isCnForm,
    ...otherProps
  } = props;

  const usedComponentList: any[] = [];
  const formInstance = useRef(null);
  const oldSchema = useRef(null);
  const isDesign = isDesignMode(props);
  const formRef = useRef(null);
  const urlParams = _context?.state?.urlParams || {};
  const {
    readOnly: formReadOnly,
    labelAlign,
    wrapperAlign,
    labelWidth,
  } = formStyle || {};
  const isFormReadOnly = executeObjectExpr(
    formReadOnly,
    {
      [__formValue__]: {},
      [__filterValue__]: {},
      [__dataSource__]: _context?.state,
      [__extraParam__]: {
        openDialogMode: get(
          _context?.state?.valueOf,
          `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`,
        ),
      },
    },
    {},
    _context?.state,
  );
  const oldFormReadOnly = useRef(isFormReadOnly);
  const { deferRender, dataOrigin } = defaultParams || {};
  const [defer, setDefer] = useState(
    deferRender === true && dataOrigin === 'request',
  );
  // 记录默认值请求需要等待哪些组件请求完成
  const waitComponentList = useRef([]);
  const waitComponentMap = useRef({});
  const configMap = useRef({});
  const getFormValue = useCallback(() => {
    if (typeof _dataSource === 'object') {
      return transProxyToObject(_dataSource);
    }
    return null;
  }, []);

  const getUrlParams = () => {
    return _context?.state?.urlParams || {};
  };

  // 设计态默认值的兼容逻辑
  if (isDesign === true) {
    if (dataOrigin === dataOriginStatic) {
      let tempDefaultValue = getFormDefaultValue(defaultParams, {
        urlParamsDataSource: urlParams,
        state: _context?.state,
        isDesign,
        formConfig: config,
      });
      if (isArrayNotEmpty(config)) {
        config.forEach((item) => {
          if (item?.name && item?.componentName) {
            if (item.componentName === 'CnArraySubAreaCard') {
              if (!isPlainObject(tempDefaultValue)) {
                tempDefaultValue = {};
              }
              if (!tempDefaultValue[item.name]) {
                tempDefaultValue[item.name] = [{}];
              }
            }
          }
        });
      }
      if (isPlainObject(tempDefaultValue)) {
        formInstance?.current?.setValues?.(tempDefaultValue, 'overwrite');
      }
    }
  }

  useImperativeHandle(ref, () => ({
    load() {
      getRemoteDefaultValue();
    },
    getFormInstance() {
      return formInstance.current;
    },
    getFormRef() {
      return formRef?.current;
    },
    reRender() {
      // reRender();
    },
  }));

  const getRemoteDefaultValue = () => {
    const {
      dataOrigin,
      requestConfig = {},
      afterRequest = {},
    } = defaultParams || {};
    const formValue = formInstance?.current?.values;

    if (dataOrigin === 'request') {
      const p = getFormDefaultValue(defaultParams, {
        urlParamsDataSource: urlParams,
        state: _context?.state,
        isDesign,
        formConfig: config,
        getExtraParam: () => {
          return {
            openDialogMode: get(
              _context?.state?.valueOf,
              `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`,
            ),
          };
        },
      });
      let newFormValue;
      if (isPlainObject(p)) {
        newFormValue = { ...(formValue || {}), ...(p || {}) };
        formInstance?.current?.setInitialValues?.(
          cloneDeep(newFormValue),
          'overwrite',
        );
      } else if (p?.then) {
        p.then(
          (result) => {
            if (isPlainObject(result)) {
              newFormValue = { ...(result || {}) };
              formInstance?.current?.setInitialValues?.(
                cloneDeep(newFormValue),
                'overwrite',
              );
            }
            setDefer(false);
          },
          () => {
            setDefer(false);
          },
        ).then((res) => {
          if (dataOrigin === 'request' && requestConfig?.url) {
            if (afterRequest?.optType) {
              const action = getButtonAction({
                ...afterRequest,
                position: ButtonPosition.formDefaultValueAfterRequestSuccess,
              });
              action?.({
                position: ButtonPosition.formDefaultValueAfterRequestSuccess,
                urlParamsDataSource: urlParams,
                recordDataSource: newFormValue,
                state: _context?.state,
                buttonConfig: afterRequest,
                _context,
              });
            }
          }
        });
      }
    }
  };

  useEffect(() => {
    const { requestConfig } = dynamicConfig || {};
    if (isPlainObject(requestConfig) && requestConfig.url) {
      makeRequest({
        buttonConfig: {
          options: {
            requestConfig,
          },
        },
        state: _context?.state,
        needSuccessToast: false,
        isDesign,
        urlParamsDataSource: urlParams,
      }).then((res) => {
        if (res) {
          const newRes = getRealResponse(res);
          const { success, data } = newRes || {};
          if (success && Array.isArray(data) && data.length > 0) {
            // setConfig(data);
          }
        }
        getRemoteDefaultValue();
      });
    } else {
      getRemoteDefaultValue();
    }
    return () => {
      if (_dataSourceName) {
        const temp = _context?.state?.[_dataSourceName];
        if (isPlainObject(temp) && !isEmpty(temp)) {
          _context?.setState({
            [_dataSourceName]: {},
          });
        }
      }
    };
  }, []);

  const generateForm = (formValue, otherConfig) => {
    const { setInitialValues } = otherConfig || {};
    const formOptions = {
      effects() {
        onFormValuesChange((form) => {
          if (form.values) {
            const temp = cloneDeep(toJS(form.values));
            if (_dataSourceName && temp) {
              _context?.setState({
                [_dataSourceName]: temp,
              });
            }
          }
        });

        function handleButtons(buttonList, parentName) {
          if (Array.isArray(buttonList) && buttonList.length > 0) {
            for (const item of buttonList) {
              const { primaryKey, hidden, disabled, optType } = item || {};
              if (primaryKey && parentName) {
                let buttonName = `${parentName}.*.${primaryKey}`;
                // 树表格兼容逻辑
                const secondButtonName = `${parentName}.*.children.*.${primaryKey}`;
                const isArrayTableAdd = optType === 'arrayTableAdd';
                if (isArrayTableAdd) {
                  buttonName = `${parentName}.${primaryKey}`;
                }
                if (hidden !== undefined && hidden !== '' && hidden !== false) {
                  onFieldReact(buttonName, (field, form) => {
                    const objExprArgMap = {
                      [__dataSource__]: _context?.state,
                      [__formValue__]: form?.values,
                    };
                    const { index } = field;
                    let currentRow = {};
                    if (typeof index === 'number') {
                      const temp = field?.query?.(parentName)?.value?.();
                      if (temp && temp[index]) {
                        currentRow = temp[index];
                      }
                    }
                    objExprArgMap[__arrayTableCurrentRow__] = currentRow;
                    field.hidden = executeObjectExpr(
                      hidden,
                      objExprArgMap,
                      currentRow,
                      _context?.state,
                      index,
                      form?.values || {},
                    );
                  });
                  // onFieldReact(secondButtonName,(field, form)=>{
                  //   const objExprArgMap = {
                  //     [__dataSource__]: _context?.state,
                  //     [__formValue__]: form?.values,
                  //   };
                  //   let currentRow = {};
                  //   const index = field.index;
                  //   if(field?.path?.segments?.length === 5) {
                  //     let path = field.path.segments.slice(0, 4);
                  //     const tempRow = field?.form?.getValuesIn?.(path);
                  //     if(isPlainObject(tempRow)) {
                  //       currentRow = tempRow;
                  //     }
                  //   }
                  //   objExprArgMap[__arrayTableCurrentRow__] = currentRow
                  //   field.hidden = executeObjectExpr(hidden, objExprArgMap, currentRow, _context?.state, index, form?.values || {});
                  // })
                }
                if (
                  disabled !== undefined &&
                  disabled !== '' &&
                  disabled !== false
                ) {
                  onFieldReact(buttonName, (field, form) => {
                    const objExprArgMap = {
                      [__dataSource__]: _context?.state,
                      [__formValue__]: form?.values,
                    };
                    const { index } = field;
                    let currentRow = {};
                    if (typeof index === 'number') {
                      const temp = field?.query?.(parentName)?.value?.();
                      if (temp && temp[index]) {
                        currentRow = temp[index];
                      }
                    }
                    objExprArgMap[__arrayTableCurrentRow__] = currentRow;
                    if (isArrayTableAdd) {
                      field.disabled = executeObjectExpr(
                        disabled,
                        objExprArgMap,
                        currentRow,
                        _context?.state,
                        index,
                        form?.values || {},
                      );
                    } else {
                      field.setComponentProps({
                        disabled: executeObjectExpr(
                          disabled,
                          objExprArgMap,
                          currentRow,
                          _context?.state,
                          index,
                          form?.values || {},
                        ),
                      });
                    }
                  });
                }
              }
            }
          }
        }

        function handleConfig(list, parentName, extraConfig) {
          if (isArrayNotEmpty(list)) {
            const { parentComponentName } = extraConfig || {};
            // 父组件是Compose组件
            const isCompose = false;
            for (const item of list) {
              const {
                events,
                name,
                componentName,
                options,
                hidden,
                disabled,
                readOnly,
                notSubmitWhenHidden,
              } = item || {};
              if (name) {
                let fieldName = name;
                if (parentName) {
                  if (isCompose) {
                    fieldName = `${parentName}.${name}`;
                  } else {
                    fieldName = `${parentName}.*.${name}`;
                  }
                }
                if (Array.isArray(events) && events.length > 0) {
                  for (const event of events) {
                    const {
                      name: eventName,
                      optType,
                      jsFunction,
                      flowList,
                    } = event || {};
                    let hook;
                    if (eventName === 'onFieldValueChange') {
                      hook = onFieldValueChange;
                    } else if (eventName === 'onFieldInputValueChange') {
                      hook = onFieldInputValueChange;
                    } else if (eventName === 'onBlur') {
                      hook = onFieldChange;
                    } else if (eventName === 'onFieldReact') {
                      hook = onFieldReact;
                    }
                    if (hook) {
                      if (
                        optType === 'jsAction' &&
                        typeof jsFunction === 'function'
                      ) {
                        if (eventName === 'onBlur') {
                          hook(fieldName, ['active'], (field) => {
                            if (
                              field?.mounted === true &&
                              field?.active === false
                            ) {
                              jsFunction.call(
                                null,
                                field,
                                formInstance.current,
                              );
                            }
                          });
                        } else {
                          hook(fieldName, (field) => {
                            jsFunction.call(null, field, formInstance.current);
                          });
                        }
                      } else {
                        const action = getButtonAction({
                          ...event,
                          position: ButtonPosition.formItemEvent,
                        });
                        if (typeof action === 'function') {
                          const callback = (field) => {
                            action({
                              buttonConfig: {
                                ...event,
                                position: ButtonPosition.formItemEvent,
                                options: {
                                  ...event,
                                },
                              },
                              position: ButtonPosition.formItemEvent,
                              componentProps: props,
                              state: _context?.state,
                              urlParamsDataSource: getUrlParams(),
                              recordDataSource: {
                                realize: () => {
                                  return formInstance?.current?.values;
                                },
                              },
                              formInstance: {
                                realize: () => {
                                  return formInstance?.current;
                                },
                              },
                              _context,
                              formRef: {
                                realize: () => {
                                  return formRef?.current;
                                },
                              },
                              field,
                            });
                          };
                          if (eventName === 'onBlur') {
                            hook(fieldName, ['active'], (field) => {
                              if (
                                field?.visited === true &&
                                field?.active === false
                              ) {
                                callback(field);
                              }
                            });
                          } else {
                            hook(fieldName, callback);
                          }
                        }
                      }
                    }
                  }
                }
                if (hidden !== undefined && hidden !== '' && hidden !== false) {
                  onFieldReact(fieldName, (field, form) => {
                    const objExprArgMap = {
                      [__dataSource__]: _context?.state,
                      [__formValue__]: form?.values,
                      [__filterValue__]: form?.values,
                      [__extraParam__]: {
                        openDialogMode: get(
                          _context?.state?.valueOf,
                          `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`,
                        ),
                      },
                    };

                    let currentRow = {};
                    if (parentName && !isCompose) {
                      const { index } = field;
                      if (typeof index === 'number') {
                        const temp = field?.query?.(parentName)?.value?.();
                        if (temp && temp[index]) {
                          currentRow = temp[index];
                        }
                      }
                      objExprArgMap[__arrayTableCurrentRow__] = currentRow;
                    }
                    const isHidden = executeObjectExpr(
                      hidden,
                      objExprArgMap,
                      form?.values || {},
                      _context?.state,
                      currentRow,
                    );
                    if (isHidden === true) {
                      if (notSubmitWhenHidden === true) {
                        field.display = 'none';
                      } else {
                        field.hidden = isHidden;
                      }
                    } else {
                      field.hidden = isHidden;
                      field.display = 'visible';
                    }

                    if (parentName && !isCompose) {
                      const { group } = hidden || {};
                      if (group !== __arrayTableCurrentRow__) {
                        if (isHidden) {
                          field
                            .query(`..${name}${columnSuffix}`)
                            .take((target) => {
                              target.hidden = true;
                            });
                        } else {
                          field
                            .query(`..${name}${columnSuffix}`)
                            .take((target) => {
                              target.hidden = false;
                            });
                        }
                      }
                    }
                  });
                }
                if (
                  disabled !== undefined &&
                  disabled !== '' &&
                  disabled !== false
                ) {
                  onFieldReact(fieldName, (field, form) => {
                    const objExprArgMap = {
                      [__dataSource__]: _context?.state,
                      [__formValue__]: form?.values,
                      [__filterValue__]: form?.values,
                      [__extraParam__]: {
                        openDialogMode: get(
                          _context?.state?.valueOf,
                          `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`,
                        ),
                      },
                    };

                    let currentRow = {};
                    if (parentName && !isCompose) {
                      const { index } = field;
                      if (typeof index === 'number') {
                        const temp = field?.query?.(parentName)?.value?.();
                        if (temp && temp[index]) {
                          currentRow = temp[index];
                        }
                      }
                      objExprArgMap[__arrayTableCurrentRow__] = currentRow;
                    }
                    field.disabled = executeObjectExpr(
                      disabled,
                      objExprArgMap,
                      form?.values || {},
                      _context?.state,
                      currentRow,
                    );
                  });
                }
                if (readOnly !== undefined && readOnly !== '') {
                  onFieldReact(fieldName, (field, form) => {
                    const objExprArgMap = {
                      [__dataSource__]: _context?.state,
                      [__formValue__]: form?.values,
                      [__filterValue__]: form?.values,
                      [__extraParam__]: {
                        openDialogMode: get(
                          _context?.state?.valueOf,
                          `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`,
                        ),
                      },
                    };
                    let currentRow = {};
                    if (parentName && !isCompose) {
                      const { index } = field;
                      if (typeof index === 'number') {
                        const temp = field?.query?.(parentName)?.value?.();
                        if (temp && temp[index]) {
                          currentRow = temp[index];
                        }
                      }
                      objExprArgMap[__arrayTableCurrentRow__] = currentRow;
                    }
                    field.readOnly = executeObjectExpr(
                      readOnly,
                      objExprArgMap,
                      form?.values || {},
                      _context?.state,
                      currentRow,
                    );
                  });
                }
              }
              if (isArrayNotEmpty(options?.config)) {
                if (isRecursionComponent(componentName)) {
                  handleConfig(options?.config, name);
                  if (componentName !== 'CnArraySubAreaCard') {
                    handleButtons(options?.buttons, name);
                  }
                }
              }
            }
          }
        }
        handleConfig(config);
      },
    };
    if (formValue && Object.keys(formValue).length > 0) {
      formOptions.values = cloneDeep(formValue);
      if (setInitialValues) {
        formOptions.initialValues = cloneDeep(formValue);
      }
    }
    if (isFormReadOnly) {
      formOptions.readOnly = isFormReadOnly;
    }
    const result = createForm(formOptions);
    onCreateForm && onCreateForm(result);
    return result;
  };

  if (!formInstance.current) {
    if (parentFormInstance) {
      formInstance.current = parentFormInstance;
    } else {
      let formDefaultValue = getFormValue();
      const tempResult = calculateWaitComponentList(config, defaultParams);
      if (isArrayNotEmpty(tempResult.waitComponentList)) {
        waitComponentList.current = tempResult.waitComponentList;
      }
      if (!isEmpty(tempResult.configMap)) {
        configMap.current = tempResult.configMap;
      }
      if (!isEmpty(tempResult.waitComponentMap)) {
        waitComponentMap.current = tempResult.waitComponentMap;
      }
      if (dataOrigin === dataOriginStatic) {
        const p = getFormDefaultValue(defaultParams, {
          urlParamsDataSource: urlParams,
          state: _context?.state,
          isDesign,
          formConfig: config,
          ignoreDefaultSelectFormRequest: true,
        });
        if (isPlainObject(p)) {
          formDefaultValue = { ...(formDefaultValue || {}), ...(p || {}) };
          if (_dataSourceName) {
            _context?.setState({
              [_dataSourceName]: { ...formDefaultValue },
            });
          }
        }
      }
      formInstance.current = generateForm(formDefaultValue, {
        setInitialValues: true,
      });
    }
  }

  const generateFormItemSchema = (item) => {
    const formValue = toJS(formInstance.current?.values);

    const formItem = makeFormItemSchema({
      formValue,
      formItemConfig: item,
      isDesign,
      urlParams,
      state: _context?.state,
      usedComponentList,
      formProps: props,
      _context,
      formInstance: formInstance?.current,
      getFormInstance: () => {
        return formInstance.current;
      },
    });
    if (formItem) {
      return formItem;
    }
  };

  const generateSchema = () => {
    if (isArrayNotEmpty(config)) {
      return generateNormalFormSchema(config);
    }
  };

  const generateNormalFormSchema = (tempFormConfig) => {
    let defaultParent = 'root';
    const tree: any = {
      root: {
        type: 'object',
        properties: {
          [`root_${CnFormGrid}`]: {
            type: 'void',
            'x-component': CnFormGrid,
            'x-component-props': {},
            properties: {},
          },
        },
        _componentName: 'root',
        _name: 'root',
      },
    };
    if (Array.isArray(tempFormConfig) && tempFormConfig.length > 0) {
      const newConfig = cloneDeepWith(tempFormConfig, (value) => {
        if (React.isValidElement(value)) {
          return value;
        }
      });
      newConfig.forEach((item = {}) => {
        const { name, componentName } = item;
        const componentDefine = getRunTimeItem(componentMap, componentName);
        const { isFormContainer } = componentDefine || {};
        const parent = tree[defaultParent];
        if (isFormContainer) {
          if (componentName === CnCard) {
            tree[name] = generateFormItemSchema(item);
            tree[name]._parent = 'root';
          } else if (componentName === CnCardSubCard) {
            if (
              parent?._componentName === CnCard ||
              parent?._componentName === 'root'
            ) {
              tree[name] = generateFormItemSchema(item);
              if (tree[name]) {
                tree[name]._parent = defaultParent;
              }
            } else if (parent?._componentName === CnCardSubCard) {
              const temp = parent?._parent || 'root';
              tree[name] = generateFormItemSchema(item);
              if (tree[name]) {
                tree[name]._parent = tree[temp]._name || 'root';
              }
            }
          }
          defaultParent = name;
        } else {
          tree[name] = generateFormItemSchema(item);
          if (tree[name]) {
            tree[name]._parent = defaultParent;
          }
        }
        if (tree[name]) {
          tree[name]._name = name;
          tree[name]._componentName = componentName;
        }
        if (tree[name]?._parent) {
          const parentSchema = tree[tree[name]._parent];
          if (parentSchema?._componentName === CnCardSubCard) {
            const { _name } = parentSchema;
            const formGrid = parentSchema.properties[`${_name}_${CnFormGrid}`];
            if (formGrid?.properties) {
              formGrid.properties[name] = tree[name];
            }
          } else if (
            parentSchema?._componentName === 'root' &&
            !isFormContainer
          ) {
            const formGrid = parentSchema.properties[`root_${CnFormGrid}`];
            if (formGrid?.properties) {
              formGrid.properties[name] = tree[name];
            }
          } else if (parentSchema?._componentName === CnCard) {
            if (componentName === CnCardSubCard) {
              parentSchema.properties[name] = tree[name];
            } else {
              const { _name } = parentSchema;
              const formGrid =
                parentSchema.properties[`${_name}_${CnFormGrid}`];
              if (formGrid?.properties) {
                formGrid.properties[name] = tree[name];
              }
            }
          } else if (parentSchema?.properties) {
            parentSchema.properties[name] = tree[name];
          }
        }
      });
    }
    return tree.root;
  };

  const getAgreement = (formValue) => {
    const result = [];
    if (isArrayNotEmpty(config)) {
      config.forEach((item) => {
        if (item.componentName === 'CnAgreement') {
          const { name, options } = item;
          if (name) {
            const { labelText } = options || {};
            result.push(
              <CnFormField
                name={name}
                required
                requiredMessage={'请阅读并同意协议'}
              >
                <CnAgreementView
                  labelText={calculateTextExprValue(labelText, {
                    recordDataSource: formValue,
                    state: _context?.state,
                  })}
                />
              </CnFormField>,
            );
          }
        }
      });
    }
    return result;
  };

  const getButtons = () => {
    if (isCnForm) {
      const btnDom = [];
      if (isArrayNotEmpty(buttons)) {
        const formValue = formInstance?.current?.values;
        const state = _context?.state;
        buttons.forEach((item, index) => {
          const {
            iconType,
            primaryKey,
            optType,
            options = {},
            children,
            type,
            hidden,
            disabled,
            ...rest
          } = item;
          const isHidden = executeObjectExpr(
            hidden,
            {
              [__filterValue__]: formValue || {},
              [__formValue__]: formValue || {},
              [__dataSource__]: state,
              [__extraParam__]: {},
            },
            formValue || {},
            state,
          );
          if (isHidden) {
            return null;
          }
          const action = getButtonAction({
            ...item,
            position: ButtonPosition.form,
          });
          const componentDefine = getRunTimeItem({}, optType);
          const btnProps = {
            size: 'large',
            fullWidth: true,
            type,
          };
          let needShowLoading;
          if (optType === 'submit') {
            needShowLoading = true;
          } else if (optType === 'flowAction') {
            const hasSubmitAction = options?.flowList?.find?.(
              (item) => item?.optType === 'submit',
            );
            if (hasSubmitAction) {
              needShowLoading = true;
            }
          }
          if (needShowLoading) {
            btnProps.loading = formInstance?.current?.submitting;
            btnProps.disabled = formInstance?.current?.submitting;
          }
          if (componentDefine?.component) {
            const component = getRealizeValue(componentDefine.component);
            if (component) {
              btnDom.push(
                React.createElement(component, {
                  children,
                  ...btnProps,
                  buttonConfig: item,
                  state: _context?.state,
                  _context,
                  [_getFormValues]: () => {
                    return formInstance?.current?.values;
                  },
                }),
              );
            }
          } else if (action) {
            btnProps.onClick = action.bind(this, {
              componentProps: props,
              buttonConfig: item,
              position: ButtonPosition.form,
              state: _context?.state,
              urlParamsDataSource: urlParams,
              recordDataSource: {
                realize: () => {
                  return formInstance?.current?.values;
                },
              },
              formInstance: {
                realize: () => {
                  return formInstance?.current;
                },
              },
              _context,
              jsParamList: [
                {
                  form: formInstance?.current,
                  state: _context?.state,
                },
              ],
            });
            btnDom.push(
              <CnButton key={index} {...btnProps}>
                {children}
              </CnButton>,
            );
          }
        });
        if (isArrayNotEmpty(btnDom)) {
          return (
            <>
              {getAgreement(formValue)}
              <CnBox flex={1} direction='row' spacing={12}>
                {btnDom}
              </CnBox>
            </>
          );
        }
      }
    }
  };

  // 设计态默认值的兼容逻辑
  if (isDesign === true) {
    if (dataOrigin === dataOriginStatic) {
      let tempDefaultValue = getFormDefaultValue(defaultParams, {
        urlParamsDataSource: urlParams,
        state: _context?.state,
        isDesign,
        formConfig: config,
        ignoreDefaultSelectFormRequest: true,
      });
      if (isArrayNotEmpty(config)) {
        config.forEach((item) => {
          if (item?.name && item?.componentName) {
            if (item.componentName === 'CnFormArrayCard') {
              if (!isPlainObject(tempDefaultValue)) {
                tempDefaultValue = {};
              }
              if (!tempDefaultValue[item.name]) {
                tempDefaultValue[item.name] = [{}];
              }
            }
          }
        });
      }
      if (isPlainObject(tempDefaultValue)) {
        formInstance?.current?.setValues?.(tempDefaultValue, 'overwrite');
      }
    }
  }

  let needCreateNewForm = false;
  const schema = generateSchema();
  if (schema && oldSchema.current) {
    if (
      !isEqualWith(schema, oldSchema.current, (objValue, othValue) => {
        if (objValue instanceof Function && othValue instanceof Function) {
          return true;
        }
      })
    ) {
      needCreateNewForm = true;
    }
  }
  if (oldFormReadOnly?.current !== isFormReadOnly) {
    needCreateNewForm = true;
  }
  if (needCreateNewForm) {
    formInstance.current = generateForm(toJS(formInstance.current?.values));
  }
  oldSchema.current = { ...schema };
  oldFormReadOnly.current = isFormReadOnly;

  const extraConfig = {};

  const buttonDom = (
    <Observer>
      {() => {
        return getButtons();
      }}
    </Observer>
  );
  if (buttonDom) {
    extraConfig.hasFooterSubmit = false;
    extraConfig.footerConfig = {
      customRender: <div />,
      children: buttonDom,
    };
  } else {
    extraConfig.hasFooterSubmit = false;
  }

  extraConfig.formLayoutProps = {};
  if (labelAlign) {
    extraConfig.formLayoutProps.labelAlign = labelAlign;
  }
  if (wrapperAlign) {
    extraConfig.formLayoutProps.wrapperAlign = wrapperAlign;
  }
  if (labelWidth) {
    extraConfig.formLayoutProps.labelWidth = labelWidth;
  }

  if (!isDesign && defer) {
    return null;
  }
  // form用到的组件列表
  const formComponents = getFormExtraComponents(usedComponentList);
  return (
    <UICnForm
      ref={formRef}
      form={formInstance.current}
      schema={schema}
      components={formComponents}
      {...extraConfig}
    />
  );
}

const CnForm = forwardRef(View);

(CnForm as any).displayName = 'CnForm';

export { CnForm };
