var _excluded = ["children"],
    _excluded2 = ["className", "meta", "children", "isFieldChildren", "showValidateMessage", "colon", "layout", "labelAlign", "inputAlign", "border"],
    _excluded3 = ["className", "style", "label", "name", "required", "noStyle", "tooltip", "intro", "customField", "disabled", "colon", "rules", "children", "messageVariables", "trigger", "validateTrigger", "onClick", "shouldUpdate", "dependencies", "labelWidth", "labelAlign", "labelClass", "showValidateMessage", "inputAlign", "errorMessageAlign", "border", "layout"];

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

/* eslint-disable no-console */
import React from 'react';
import clsx from 'clsx';
import { Field as RcField } from 'rc-field-form';
import FieldContext from 'rc-field-form/lib/FieldContext';
import Field from '../field';
import { toArray } from '../uploader/utils';
import { FIELD_KEY } from '../field/Field';
import { COMPONENT_TYPE_KEY } from '../utils/constant';
import { FormContext } from './FormContext';
import ConfigProviderContext from '../config-provider/ConfigProviderContext';
import { devWarning } from '../utils/dev-log';
var MemoInput = /*#__PURE__*/React.memo(function (_ref) {
  var children = _ref.children,
      props = _objectWithoutPropertiesLoose(_ref, _excluded);

  return /*#__PURE__*/React.cloneElement(children, props);
}, function (prev, next) {
  return prev.value === next.value && prev.update === next.update;
});

var FormItemLayout = function FormItemLayout(props) {
  var className = props.className,
      meta = props.meta,
      children = props.children,
      isFieldChildren = props.isFieldChildren,
      showValidateMessage = props.showValidateMessage,
      colon = props.colon,
      layout = props.layout,
      labelAlign = props.labelAlign,
      inputAlign = props.inputAlign,
      border = props.border,
      fieldProps = _objectWithoutPropertiesLoose(props, _excluded2);

  var _React$useContext = React.useContext(ConfigProviderContext),
      prefixCls = _React$useContext.prefixCls,
      createNamespace = _React$useContext.createNamespace;

  var _createNamespace = createNamespace('form', prefixCls),
      bem = _createNamespace[0];

  var context = React.useContext(FormContext);
  var itemLayout = layout != null ? layout : context.layout;
  var itemBorder = border != null ? border : context.border;
  var itemColon = colon != null ? colon : context.colon;
  var itemShowValidateMessage = showValidateMessage != null ? showValidateMessage : context.showValidateMessage;
  var itemLabelAlign = labelAlign != null ? labelAlign : context.labelAlign;
  var itemInputAlign = inputAlign != null ? inputAlign : context.inputAlign;
  var error = meta && meta.errors.length > 0;
  var errorMessage = itemShowValidateMessage && error ? meta.errors[0] : null;

  var attrs = _extends({}, fieldProps, {
    className: clsx(bem({
      vertical: itemLayout === 'vertical'
    }), className),
    colon: itemColon,
    error: error,
    errorMessage: errorMessage,
    labelAlign: itemLabelAlign,
    inputAlign: itemInputAlign,
    border: itemBorder
  });

  if (isFieldChildren) return /*#__PURE__*/React.cloneElement(children, attrs);
  return /*#__PURE__*/React.createElement(Field, attrs, children);
};

var FormItem = function FormItem(props) {
  var _type;

  var className = props.className,
      style = props.style,
      label = props.label,
      name = props.name,
      required = props.required,
      noStyle = props.noStyle,
      tooltip = props.tooltip,
      intro = props.intro,
      customField = props.customField,
      disabled = props.disabled,
      colon = props.colon,
      rules = props.rules,
      children = props.children,
      messageVariables = props.messageVariables,
      _props$trigger = props.trigger,
      trigger = _props$trigger === void 0 ? 'onChange' : _props$trigger,
      validateTrigger = props.validateTrigger,
      onClick = props.onClick,
      shouldUpdate = props.shouldUpdate,
      dependencies = props.dependencies,
      labelWidth = props.labelWidth,
      labelAlign = props.labelAlign,
      labelClass = props.labelClass,
      showValidateMessage = props.showValidateMessage,
      inputAlign = props.inputAlign,
      errorMessageAlign = props.errorMessageAlign,
      border = props.border,
      layout = props.layout,
      fieldProps = _objectWithoutPropertiesLoose(props, _excluded3);

  var _React$useContext2 = React.useContext(FieldContext),
      contextValidateTrigger = _React$useContext2.validateTrigger;

  var mergedValidateTrigger = validateTrigger !== undefined ? validateTrigger : contextValidateTrigger;
  var updateRef = React.useRef(0);
  updateRef.current += 1;
  var isFieldChildren = ((_type = children.type) == null ? void 0 : _type[COMPONENT_TYPE_KEY]) === FIELD_KEY || customField;

  function renderLayout(baseChildren, fieldId, meta, isRequired) {
    if (noStyle) {
      return baseChildren;
    }

    return /*#__PURE__*/React.createElement(FormItemLayout, {
      isFieldChildren: isFieldChildren,
      className: className,
      style: style,
      label: label,
      tooltip: tooltip,
      intro: intro,
      required: isRequired,
      disabled: disabled,
      htmlFor: fieldId,
      meta: meta,
      colon: colon,
      border: border,
      layout: layout,
      labelWidth: labelWidth,
      labelAlign: labelAlign,
      labelClass: labelClass,
      inputAlign: inputAlign,
      errorMessageAlign: errorMessageAlign,
      showValidateMessage: showValidateMessage,
      onClick: onClick
    }, baseChildren);
  }

  var isRenderProps = typeof children === 'function';

  if (!name && !isRenderProps && !props.dependencies) {
    return renderLayout(children);
  }

  var variables = {};

  if (typeof label === 'string') {
    variables.label = label;
  }

  if (messageVariables) {
    variables = _extends({}, variables, messageVariables);
  }

  return /*#__PURE__*/React.createElement(RcField, _extends({}, fieldProps, {
    name: name,
    shouldUpdate: shouldUpdate,
    dependencies: dependencies,
    rules: rules,
    trigger: trigger,
    validateTrigger: mergedValidateTrigger
  }), function (control, meta, context) {
    var childNode = null;
    var isRequired = required !== undefined ? required : !!(rules && rules.some(function (rule) {
      if (rule && typeof rule === 'object' && rule.required) {
        return true;
      }

      return false;
    }));
    var fieldId = (toArray(name).length && meta ? meta.name : []).join('_');

    if (shouldUpdate && dependencies) {
      devWarning('Form.Item', "`shouldUpdate` and `dependencies` shouldn't be used together.");
    }

    if (isRenderProps) {
      if ((shouldUpdate || dependencies) && !name) {
        childNode = children(context);
      } else {
        if (!(shouldUpdate || dependencies)) {
          devWarning('Form.Item', '`children` of render props only work with `shouldUpdate` or `dependencies`.');
        }

        if (name) {
          devWarning('Form.Item', "Do not use `name` with `children` of render props since it's not a field.");
        }
      } // not render props

    } else if (dependencies && !name) {
      devWarning('Form.Item', 'Must set `name` or use render props when `dependencies` is set.');
    } else if ( /*#__PURE__*/React.isValidElement(children)) {
      var childProps = _extends({}, children.props, control);

      if (!childProps.id) {
        childProps.id = fieldId;
      }

      if (disabled) {
        childProps.disabled = disabled;
      } // We should keep user origin event handler


      var triggers = new Set([].concat(toArray(trigger), toArray(mergedValidateTrigger)));
      triggers.forEach(function (eventName) {
        childProps[eventName] = function () {
          var _control$eventName, _children$props$event, _children$props;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          (_control$eventName = control[eventName]) == null ? void 0 : _control$eventName.call.apply(_control$eventName, [control].concat(args));
          (_children$props$event = (_children$props = children.props)[eventName]) == null ? void 0 : _children$props$event.call.apply(_children$props$event, [_children$props].concat(args));
        };
      });
      childNode = /*#__PURE__*/React.createElement(MemoInput, {
        value: control[props.valuePropName || 'value'],
        update: updateRef.current
      }, /*#__PURE__*/React.cloneElement(children, childProps));

      if (isFieldChildren) {
        childProps.value = childProps.value || '';
        childNode = /*#__PURE__*/React.cloneElement(children, childProps);
      }
    } else {
      if (name) {
        devWarning('Form.Item', '`name` is only used for validate React element. If you are using Form.Item as layout display, please remove `name` instead.');
      }

      childNode = children;
    }

    return renderLayout(childNode, fieldId, meta, isRequired);
  });
};

export default FormItem;