import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import React from 'react';
import classNames from 'classnames';
import isEqual from 'lodash/isEqual';
import { ConfigContext } from '../config-provider/context';
import Grid from '../grid';
import Tooltip from '../tooltip';
import Popover from '../popover';
import Icons from '../icon';
import { Field } from '../components/rc-field-form';
import { FormContext, FormItemContext } from './context';
import { toArray, getFieldId } from './util';
import useFrameState from './hooks/useFrameState';
var Row = Grid.Row,
    Col = Grid.Col;
var QuestionFill = Icons.QuestionFill;
var NAME_SPLIT = '_SPLIT_';

var FormItem = function FormItem(props) {
  var customPrefixCls = props.prefixCls,
      children = props.children,
      labelName = props.label,
      itemCenter = props.itemCenter,
      labelWidth = props.labelWidth,
      required = props.required,
      tips = props.tips,
      trigger = props.trigger,
      name = props.name,
      rules = props.rules,
      shouldUpdate = props.shouldUpdate,
      dependencies = props.dependencies,
      validateTrigger = props.validateTrigger,
      htmlFor = props.htmlFor,
      noStyle = props.noStyle,
      labelCol = props.labelCol,
      wrapperCol = props.wrapperCol,
      fieldKey = props.fieldKey,
      tooltip = props.tooltip,
      popover = props.popover,
      className = props.className,
      style = props.style,
      extra = props.extra,
      messageVariables = props.messageVariables,
      rightExtra = props.rightExtra,
      reset = _objectWithoutProperties(props, ["prefixCls", "children", "label", "itemCenter", "labelWidth", "required", "tips", "trigger", "name", "rules", "shouldUpdate", "dependencies", "validateTrigger", "htmlFor", "noStyle", "labelCol", "wrapperCol", "fieldKey", "tooltip", "popover", "className", "style", "extra", "messageVariables", "rightExtra"]);

  var _React$useContext = React.useContext(ConfigContext),
      getPrefixClassName = _React$useContext.getPrefixClassName;

  var _React$useContext2 = React.useContext(FormItemContext),
      updateItemErrors = _React$useContext2.updateItemErrors;

  var formContext = React.useContext(FormContext);
  var formName = formContext.name,
      contextLabelCol = formContext.labelCol,
      contextWrapperCol = formContext.wrapperCol,
      disabled = formContext.disabled,
      layout = formContext.layout;

  var _useFrameState = useFrameState({}),
      _useFrameState2 = _slicedToArray(_useFrameState, 2),
      inlineErrors = _useFrameState2[0],
      setInlineErrors = _useFrameState2[1];

  var nameRef = React.useRef([]);
  var prefixCls = getPrefixClassName('form-item', customPrefixCls);
  var isRenderProps = typeof children === 'function';
  var nameIsExit = name !== undefined && name !== null;
  var updateChildItemErrors = noStyle ? updateItemErrors : function (subName, subErrors, originSubName) {
    setInlineErrors(function () {
      var prevInlineErrors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

      // Clean up origin error when name changed
      if (originSubName !== subName) {
        delete prevInlineErrors[originSubName];
      }

      if (!isEqual(prevInlineErrors[subName], subErrors)) {
        return _objectSpread(_objectSpread({}, prevInlineErrors), {}, _defineProperty({}, subName, subErrors));
      }

      return prevInlineErrors;
    });
  };

  var renderTooltip = function renderTooltip() {
    var defaultIcon = /*#__PURE__*/React.createElement(QuestionFill, null);
    if (!tooltip) return null;
    /* eslint-disable no-unneeded-ternary */

    if (_typeof(tooltip) === 'object' && ! /*#__PURE__*/React.isValidElement(tooltip)) {
      var icon = tooltip.icon,
          resetToolTipProps = _objectWithoutProperties(tooltip, ["icon"]);

      return /*#__PURE__*/React.createElement(Tooltip, Object.assign({}, resetToolTipProps), icon ? icon : defaultIcon);
    }

    return /*#__PURE__*/React.createElement(Tooltip, {
      title: tooltip
    }, defaultIcon);
  };

  var renderPopover = function renderPopover() {
    var defaultIcon = /*#__PURE__*/React.createElement(QuestionFill, null);
    if (!popover) return null;
    /* eslint-disable no-unneeded-ternary */

    if (_typeof(popover) === 'object' && ! /*#__PURE__*/React.isValidElement(popover)) {
      var icon = popover.icon,
          resetPopoverProps = _objectWithoutProperties(popover, ["icon"]);

      return /*#__PURE__*/React.createElement(Popover, Object.assign({}, resetPopoverProps), icon ? icon : defaultIcon);
    }

    return /*#__PURE__*/React.createElement(Popover, {
      title: popover
    }, defaultIcon);
  };

  var renderRowItem = function renderRowItem(childrenWithNewProps, isRequired, meta, fieldItemName) {
    var _classNames;

    if (noStyle) return /*#__PURE__*/React.createElement(React.Fragment, null, childrenWithNewProps);
    var endLabelCol = labelCol || contextLabelCol || {};
    var endWrapperCol = wrapperCol || contextWrapperCol || {};
    var subErrorList = [];
    Object.keys(inlineErrors).forEach(function (subName) {
      subErrorList = [].concat(_toConsumableArray(subErrorList), _toConsumableArray(inlineErrors[subName] || []));
    });
    var mergedErrors; // if (help !== undefined && help !== null) {
    //   mergedErrors = toArray(help);
    // } else {

    mergedErrors = meta ? meta.errors : [];
    mergedErrors = [].concat(_toConsumableArray(mergedErrors), _toConsumableArray(subErrorList)); // }

    var endFormItemCls = classNames((_classNames = {}, _defineProperty(_classNames, prefixCls, true), _defineProperty(_classNames, "".concat(prefixCls, "-error"), mergedErrors.length > 0), _defineProperty(_classNames, "".concat(prefixCls, "-validating"), meta === null || meta === void 0 ? void 0 : meta.validating), _defineProperty(_classNames, "".concat(className), !!className), _classNames));
    var labelColClass = classNames("".concat(prefixCls, "-label"), JSON.stringify(endLabelCol) === '{}' && "".concat(prefixCls, "-label-normal"), _defineProperty({}, "".concat(prefixCls, "-no-centered"), !itemCenter));
    var controllCls = classNames("".concat(prefixCls, "-controll"), _defineProperty({}, "".concat(prefixCls, "-no-centered"), !itemCenter));
    var controllChild = classNames("".concat(prefixCls, "-controll-content-child"), {
      'has-rightExtra': rightExtra
    });
    var rightExtraCls = classNames("".concat(prefixCls, "-rightExtra"), _defineProperty({}, "".concat(prefixCls, "-no-centered"), !itemCenter));
    var labeExtraCls = classNames(_defineProperty({}, "".concat(prefixCls, "-label-required"), isRequired), "".concat(prefixCls, "-label-extra"));
    var childElement = /*#__PURE__*/React.createElement(FormItemContext.Provider, {
      value: {
        updateItemErrors: updateChildItemErrors
      }
    }, childrenWithNewProps); // 去除子formItem的栅格布局属性

    var childFormContext = _objectSpread({}, formContext);

    delete childFormContext.labelCol;
    delete childFormContext.wrapperCol;
    return /*#__PURE__*/React.createElement(Row, {
      className: endFormItemCls,
      style: style
    }, labelName ? /*#__PURE__*/React.createElement(Col, Object.assign({
      className: labelColClass
    }, endLabelCol), /*#__PURE__*/React.createElement("div", {
      className: "".concat(prefixCls, "-label-content"),
      style: layout === 'vertical' && !isRequired ? {
        paddingLeft: 0
      } : undefined
    }, /*#__PURE__*/React.createElement("label", {
      style: {
        width: labelWidth
      },
      htmlFor: htmlFor
    }, labelName), /*#__PURE__*/React.createElement("div", {
      className: labeExtraCls
    }, tooltip && renderTooltip(), popover && renderPopover()))) : null, /*#__PURE__*/React.createElement(FormContext.Provider, {
      value: childFormContext
    }, /*#__PURE__*/React.createElement(Col, Object.assign({
      className: controllCls
    }, endWrapperCol), /*#__PURE__*/React.createElement("div", {
      className: "".concat(prefixCls, "-controll-content")
    }, /*#__PURE__*/React.createElement("div", {
      className: controllChild
    }, rightExtra ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
      className: "".concat(prefixCls, "-controll-element")
    }, childElement), /*#__PURE__*/React.createElement("span", {
      className: rightExtraCls
    }, rightExtra)) : childElement)), mergedErrors.length > 0 ?
    /*#__PURE__*/

    /* eslint-disable react/no-array-index-key */
    React.createElement(React.Fragment, null, mergedErrors.map(function (error, index) {
      return /*#__PURE__*/React.createElement("div", {
        key: index,
        className: "".concat(prefixCls, "-error-tips")
      }, error);
    })) : /*#__PURE__*/React.createElement(React.Fragment, null, tips && /*#__PURE__*/React.createElement("span", {
      className: "".concat(prefixCls, "-controll-tips")
    }, tips)), extra ? /*#__PURE__*/React.createElement("div", {
      className: "".concat(prefixCls, "-controll-extra")
    }, extra) : null)));
  };

  var renderFieldChild = function renderFieldChild(control, meta, context) {
    var mergedName = toArray(name).length && meta ? meta.name : [];
    var errors = meta.errors;

    if (noStyle) {
      var originErrorName = nameRef.current.join(NAME_SPLIT);
      nameRef.current = _toConsumableArray(mergedName);

      if (fieldKey) {
        var fieldKeys = Array.isArray(fieldKey) ? fieldKey : [fieldKey];
        nameRef.current = [].concat(_toConsumableArray(mergedName.slice(0, -1)), _toConsumableArray(fieldKeys));
      }

      updateItemErrors(nameRef.current.join(NAME_SPLIT), errors, originErrorName);
    }

    var isRequired = required !== undefined ? required : !!(rules && rules.some(function (rule) {
      if (rule && rule.required) {
        return true;
      }

      if (typeof rule === 'function') {
        return rule(context) && rule(context).required;
      }

      return false;
    }));
    var fieldItemName = "".concat(formName, "_").concat(getFieldId(meta.name));
    var childNode = children;

    if ( /*#__PURE__*/React.isValidElement(children)) {
      var childProps = _objectSpread(_objectSpread({}, children.props), control);

      if (disabled) {
        childProps.disabled = disabled;
      }

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

      var triggers = new Set([].concat(_toConsumableArray(toArray(trigger)), _toConsumableArray(toArray(validateTrigger))));
      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 || _control$eventName === void 0 ? void 0 : _control$eventName.call.apply(_control$eventName, [control].concat(args));
          (_children$props$event = (_children$props = children.props)[eventName]) === null || _children$props$event === void 0 ? void 0 : _children$props$event.call.apply(_children$props$event, [_children$props].concat(args));
        };
      });
      childNode = /*#__PURE__*/React.cloneElement(children, childProps);
    } else if (isRenderProps && (shouldUpdate || dependencies) && !nameIsExit && typeof children === 'function') {
      childNode = children(context);
    }

    return /*#__PURE__*/React.createElement(React.Fragment, null, renderRowItem(childNode, isRequired, meta, fieldItemName));
  };

  if (!nameIsExit && !isRenderProps && !dependencies) {
    return renderRowItem(children, required);
  }

  var variables = {};

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

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

  return /*#__PURE__*/React.createElement(Field, Object.assign({
    rules: rules,
    name: name,
    trigger: trigger,
    validateTrigger: validateTrigger,
    messageVariables: variables,
    dependencies: dependencies,
    shouldUpdate: shouldUpdate
  }, reset), renderFieldChild);
};

FormItem.defaultProps = {
  itemCenter: true,
  trigger: 'onChange',
  validateTrigger: 'onChange'
};
FormItem.displayName = 'FormItem';
export default FormItem;