import _extends from "@babel/runtime/helpers/extends";
// http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/merge_requests/1054678
// 这个MR合并后可以去掉这个文件

function propConfigToFieldConfig(propConfig, supportVariable) {
  var name = propConfig.name,
    description = propConfig.description;
  var title = {
    label: {
      type: 'i18n',
      'en-US': name,
      'zh-CN': (description === null || description === void 0 ? void 0 : description.slice(0, 10)) || name
    },
    tip: description ? name + " | " + description : undefined
  };
  var setter = propConfig.setter || propTypeToSetter(propConfig.propType, supportVariable);
  if (supportVariable && propConfig.supportVariable !== false) {
    var _setter$props, _setter$props2, _setter$props2$setter;
    if (setter.componentName === 'MixedSetter' && (_setter$props = setter.props) !== null && _setter$props !== void 0 && _setter$props.setters && (_setter$props2 = setter.props) !== null && _setter$props2 !== void 0 && (_setter$props2$setter = _setter$props2.setters) !== null && _setter$props2$setter !== void 0 && _setter$props2$setter.every(function (setter) {
      return (setter === null || setter === void 0 ? void 0 : setter.componentName) !== 'VariableSetter' && setter !== 'VariableSetter';
    })) {
      setter.props.setters.push('VariableSetter');
    } else if (setter && setter !== 'VariableSetter' && setter.componentName !== 'VariableSetter') {
      setter = {
        componentName: 'MixedSetter',
        props: {
          setters: [setter, 'VariableSetter']
        }
      };
    }
  }
  return _extends({
    title: title
  }, propConfig, {
    // TODO 这边直接用propConfig，将setter丢在propconfig里，需要确认是否在PropConfig扩展还是换实现
    setter: setter
  });
}
function propTypeToSetter(propType, supportVariable) {
  var typeName;
  var isRequired = false;
  if (typeof propType === 'string') {
    typeName = propType;
  } else if (typeof propType === 'object') {
    typeName = propType.type;
    isRequired = propType.isRequired;
  } else {
    typeName = 'string';
  }
  // TODO: use mixinSetter wrapper
  switch (typeName) {
    case 'string':
      return {
        componentName: 'StringSetter',
        isRequired: isRequired,
        initialValue: ''
      };
    case 'number':
      return {
        componentName: 'NumberSetter',
        isRequired: isRequired,
        initialValue: 0
      };
    case 'bool':
      return {
        componentName: 'BoolSetter',
        isRequired: isRequired,
        initialValue: false
      };
    case 'oneOf':
      var dataSource = (propType.value || []).map(function (value, index) {
        var t = typeof value;
        return {
          label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : "value " + index,
          value: value
        };
      });
      var componentName = dataSource.length >= 4 ? 'SelectSetter' : 'RadioGroupSetter';
      return {
        componentName: componentName,
        props: {
          dataSource: dataSource,
          options: dataSource
        },
        isRequired: isRequired,
        initialValue: dataSource[0] ? dataSource[0].value : null
      };
    case 'element':
    case 'node':
      // TODO: use Mixin
      return {
        // slotSetter
        componentName: 'SlotSetter',
        props: {
          mode: typeName
        },
        isRequired: isRequired,
        initialValue: {
          type: 'JSSlot',
          value: []
        }
      };
    case 'shape':
    case 'exact':
      var items = (propType.value || []).map(function (item) {
        return propConfigToFieldConfig(item, supportVariable);
      });
      return {
        componentName: 'ObjectSetter',
        props: {
          config: {
            items: items,
            extraSetter: typeName === 'shape' ? propTypeToSetter('any', supportVariable) : null
          }
        },
        isRequired: isRequired,
        initialValue: function initialValue(field) {
          var data = {};
          items.forEach(function (item) {
            var initial = item.defaultValue;
            if (initial == null && item.setter && typeof item.setter === 'object') {
              initial = item.setter.initialValue;
            }
            data[item.name] = initial ? typeof initial === 'function' ? initial(field) : initial : null;
          });
          return data;
        }
      };
    case 'object':
    case 'objectOf':
      return {
        componentName: 'ObjectSetter',
        props: {
          config: {
            extraSetter: propTypeToSetter(typeName === 'objectOf' ? propType.value : 'any', supportVariable)
          }
        },
        isRequired: isRequired,
        initialValue: {}
      };
    case 'array':
    case 'arrayOf':
      return {
        componentName: 'ArraySetter',
        props: {
          itemSetter: propTypeToSetter(typeName === 'arrayOf' ? propType.value : 'any', supportVariable)
        },
        isRequired: isRequired,
        initialValue: []
      };
    case 'func':
      return {
        componentName: 'FunctionSetter',
        isRequired: isRequired
      };
    case 'color':
      return {
        componentName: 'ColorSetter',
        isRequired: isRequired
      };
    case 'oneOfType':
      return {
        componentName: 'MixedSetter',
        props: {
          // TODO:
          setters: propType.value.map(function (item) {
            return propTypeToSetter(item, supportVariable);
          })
        },
        isRequired: isRequired
      };
    default:
    // do nothing
  }
  return {
    componentName: 'MixedSetter',
    isRequired: isRequired,
    props: {}
  };
}
var NO_EVENTS = ['beforeUpload'];
var EVENT_RE = /^on|after|before[A-Z][\w]*$/;
export default function (metadata, supportVariable) {
  var _metadata$configure = metadata.configure,
    configure = _metadata$configure === void 0 ? {} : _metadata$configure;
  // TODO types后续补充
  var extendsProps = null;
  if (configure.props) {
    if (Array.isArray(configure.props)) {
      return metadata;
    }
    var _configure$props = configure.props,
      isExtends = _configure$props.isExtends,
      _configure$props$over = _configure$props.override,
      override = _configure$props$over === void 0 ? [] : _configure$props$over;
    // 不开启继承时，直接返回configure配置
    if (!isExtends) {
      return _extends({}, metadata, {
        configure: _extends({}, configure, {
          props: [].concat(override)
        })
      });
    }
    extendsProps = {};
    // 开启继承后，缓存重写内容的配置
    override.forEach(function (prop) {
      extendsProps[prop.name] = prop;
    });
  }
  if (!metadata.props) {
    return _extends({}, metadata, {
      configure: _extends({}, configure, {
        props: []
      })
    });
  }
  var _configure$component = configure.component,
    component = _configure$component === void 0 ? {} : _configure$component,
    _configure$supports = configure.supports,
    supports = _configure$supports === void 0 ? {} : _configure$supports;
  var supportedEvents = supports.events ? null : [];
  var props = [];
  metadata.props.forEach(function (prop) {
    var _prop = prop,
      name = _prop.name,
      propType = _prop.propType,
      description = _prop.description;
    if (name === 'children' && (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any')) {
      if (component.isContainer !== false) {
        component.isContainer = true;
        props.push(propConfigToFieldConfig(prop, supportVariable));
        return;
      }
    }
    if (EVENT_RE.test(name) && NO_EVENTS.indexOf(name) < 0 && (propType === 'func' || propType === 'any')) {
      if (supportedEvents) {
        supportedEvents.push({
          name: name,
          description: description
        });
        supports.events = supportedEvents;
      }
      return;
    }
    if (name === 'className' && (propType === 'string' || propType === 'any')) {
      if (supports.className == null) {
        supports.className = true;
      }
      return;
    }
    if (name === 'style' && (propType === 'object' || propType === 'any')) {
      if (supports.style == null) {
        supports.style = true;
      }
      return;
    }

    // 存在覆盖配置时
    if (extendsProps) {
      if (name in extendsProps) {
        prop = extendsProps[name];
      }
    }
    props.push(propConfigToFieldConfig(prop, supportVariable));
  });
  return _extends({}, metadata, {
    configure: _extends({}, configure, {
      props: props,
      supports: supports,
      component: component
    })
  });
}