import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
var _jsxFileName = 'src/form/ValidationField.jsx';
import React, { Component, cloneElement } from 'react';
import PropTypes from 'prop-types';
import FormItem from './FormItem';
import debounce from 'lodash.debounce';

/**
 * ValidationField
 * @description ValidationField是基于FormItem组件对校验逻辑的封装，下表未列出的属性将会传递给FormItem。
 * */

var ValidationField = function (_Component) {
    _inherits(ValidationField, _Component);

    function ValidationField(props, context) {
        _classCallCheck(this, ValidationField);

        var _this = _possibleConstructorReturn(this, (ValidationField.__proto__ || Object.getPrototypeOf(ValidationField)).call(this, props, context));

        _this.firstRender = true;

        _this.onItemChange = function (arg0, arg1, cb) {
            var _this$props = _this.props,
                name = _this$props.name,
                propUpdateItemData = _this$props.updateItemData,
                valuePropName = _this$props.valuePropName;
            var nuiFormData = _this.context.nuiFormData;

            var updateItemData = propUpdateItemData;
            if (nuiFormData) {
                if (typeof updateItemData === 'undefined') {
                    updateItemData = nuiFormData.updateItemData;
                }
            }
            if (arg0 && arg0.target) {
                if (arg1 != null) {
                    updateItemData(name, arg1, cb);
                } else if (arg0.target[valuePropName] != null) {
                    updateItemData(name, arg0.target[valuePropName], cb);
                } else if (arg0.target.nodeName === 'INPUT' || arg0.target.nodeName === 'TEXTAREA') {
                    updateItemData(name, arg0.target.value, cb);
                }
            } else {
                updateItemData(name, arg0, cb);
            }
        };

        var validateItem = props.validateItem;
        if (context.nuiFormData) {
            if (typeof validateItem === 'undefined') {
                validateItem = context.nuiFormData.validateItem;
            }
        }
        _this.itemChangeCallback = props.validateTrigger === 'onChange' ? debounce(validateItem(props.onValidate) || function () {}, props.debouncedChildren.includes[props.children.type.displayName] ? 500 : 100, {
            maxWait: 2000
        }) : validateItem(props.onValidate);
        if (props.children.props[props.valuePropName] != null && !((props.formValues && props.formValues[props.value]) != null || context.nuiFormData && context.nuiFormData.formValues && context.nuiFormData.formValues[props.name] != null)) _this.onItemChange(props.children.props[props.valuePropName]);
        return _this;
    }

    _createClass(ValidationField, [{
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(nextProps, nextContext) {
            if (nextProps.validateItem !== this.props.validateItem) {
                this.itemChangeCallback = nextProps.validateTrigger === 'onChange' ? debounce(nextProps.validateItem(nextProps.onValidate), nextProps.children.type.displayName === 'NeatUI.Input' ? 500 : 100, { maxWait: 2000 }) : nextProps.validateItem(nextProps.onValidate);
            } else if (nextContext.validateItem !== this.context.validateItem && !nextProps.validateItem) {
                this.itemChangeCallback = nextProps.validateTrigger === 'onChange' ? debounce(nextContext.nuiFormData.validateItem(nextProps.onValidate), nextProps.children.type.displayName === 'NeatUI.Input' ? 500 : 100, { maxWait: 2000 }) : nextContext.nuiFormData.validateItem(nextProps.onValidate);
            }
        }
    }, {
        key: 'render',
        value: function render() {
            var _this2 = this,
                _inputProps;

            var _props = this.props,
                inputId = _props.inputId,
                name = _props.name,
                defaultValue = _props.defaultValue,
                disabled = _props.disabled,
                onChange = _props.onChange,
                children = _props.children,
                updateItemData = _props.updateItemData,
                validateAll = _props.validateAll,
                validateTrigger = _props.validateTrigger,
                valuePropName = _props.valuePropName,
                onValidate = _props.onValidate,
                size = _props.size,
                propFormValues = _props.formValues,
                propFormErrorMsgs = _props.formErrorMsgs,
                propFormValidatingStatus = _props.formValidatingStatus,
                propValidateItem = _props.validateItem,
                propInline = _props.inline,
                other = _objectWithoutProperties(_props, ['inputId', 'name', 'defaultValue', 'disabled', 'onChange', 'children', 'updateItemData', 'validateAll', 'validateTrigger', 'valuePropName', 'onValidate', 'size', 'formValues', 'formErrorMsgs', 'formValidatingStatus', 'validateItem', 'inline']);

            var nuiFormData = this.context.nuiFormData;

            var formValues = propFormValues;
            var formErrorMsgs = propFormErrorMsgs;
            var formValidatingStatus = propFormValidatingStatus;
            var validateItem = propValidateItem;
            var inline = propInline;
            if (nuiFormData) {
                if (typeof formValues === 'undefined') {
                    formValues = nuiFormData.formValues;
                }

                if (typeof formErrorMsgs === 'undefined') {
                    formErrorMsgs = nuiFormData.formErrorMsgs;
                }

                if (typeof formValidatingStatus === 'undefined') {
                    formValidatingStatus = nuiFormData.formValidatingStatus;
                }

                if (typeof validateItem === 'undefined') {
                    validateItem = nuiFormData.validateItem;
                }

                if (typeof inline === 'undefined') {
                    inline = nuiFormData.inline;
                }
            }
            var validateStatus = 'initial';
            if (formErrorMsgs && formErrorMsgs[name] && formErrorMsgs[name].length > 0) {
                validateStatus = 'error';
            } else if (formErrorMsgs && formErrorMsgs[name] != null) {
                validateStatus = 'success';
            }
            var value = formValues && formValues[name];
            var inputProps = (_inputProps = {
                name: name,
                disabled: disabled,
                size: size
            }, _defineProperty(_inputProps, valuePropName, value), _defineProperty(_inputProps, 'inputProps', { id: 'neatui-form-' + (inputId || name) }), _defineProperty(_inputProps, 'onChange', function onChange() {
                var _children$props;

                children.props.onChange && (_children$props = children.props).onChange.apply(_children$props, arguments);
                !disabled && _this2.onItemChange(arguments.length <= 0 ? undefined : arguments[0], arguments.length <= 1 ? undefined : arguments[1], validateTrigger === 'onChange' ? _this2.itemChangeCallback : null);
            }), _inputProps);
            if (this.firstRender && (!formValues || inputProps[valuePropName] == null)) {
                inputProps[valuePropName] = children.props[valuePropName];
            }
            if (validateTrigger !== 'none') {
                inputProps[validateTrigger] = function () {
                    var _children$props2;

                    children.props[validateTrigger] && (_children$props2 = children.props)[validateTrigger].apply(_children$props2, arguments);
                    if (validateTrigger === 'onChange') {
                        !disabled && _this2.onItemChange(arguments.length <= 0 ? undefined : arguments[0], arguments.length <= 1 ? undefined : arguments[1], validateTrigger === 'onChange' ? _this2.itemChangeCallback : null);
                    } else {
                        !disabled && validateItem && validateItem(onValidate)(name);
                    }
                };
            }
            var itemProps = {
                name: name,
                disabled: disabled,
                validateStatus: validateStatus,
                inline: inline,
                size: size,
                inputId: 'neatui-form-' + (inputId || name),
                validating: formValidatingStatus && formValidatingStatus[name]
            };
            if (formErrorMsgs && formErrorMsgs[name] && formErrorMsgs[name].length > 0) {
                itemProps.helperText = formErrorMsgs[name];
            }
            var input = cloneElement(children, inputProps);
            this.firstRender = false;
            return React.createElement(
                FormItem,
                Object.assign({}, other, itemProps, {
                    __source: {
                        fileName: _jsxFileName,
                        lineNumber: 256
                    },
                    __self: this
                }),
                input
            );
        }
    }]);

    return ValidationField;
}(Component);

ValidationField.propTypes = {
    /**
     * 表单项唯一表识，与formData, errorMsg, formValidatingStatus对应属性关联
     */
    name: PropTypes.string.isRequired,
    /**
     * label 标签的文本
     */
    label: PropTypes.node,
    /**
     * input元素Id
     */
    inputId: PropTypes.string,
    /**
     * 是否禁用
     */
    disabled: PropTypes.bool,
    /**
     * @ignore
     */
    formValues: PropTypes.object,
    /**
     * @ignore
     */
    formErrorMsgs: PropTypes.object,
    /**
     * @ignore
     */
    formValidatingStatus: PropTypes.object,
    /**
     * 表单项值变化时触发
     */
    onChange: PropTypes.func,
    /**
     * 表单项值校验完成时触发
     */
    onValidate: PropTypes.func,
    /**
     * 子节点的值的属性，如 Datapicker 的是 'defaultValue'
     */
    valuePropName: PropTypes.string,
    /**
     * 子节点的触发校验的属性，如 Input 可以设置为 'onBlur'
     */
    validateTrigger: PropTypes.string,
    /**
     * @ignore
     */
    validateItem: PropTypes.func,
    /**
     * 表单项尺寸
     */
    size: PropTypes.oneOf(['small', 'medium', 'large'])
};
ValidationField.defaultProps = {
    disabled: false,
    valuePropName: 'value',
    validateTrigger: 'onChange',
    debouncedChildren: ['NeatUI.Input', 'NeatUI.AutoSuggest'],
    size: 'medium'
};
ValidationField.contextTypes = {
    nuiFormData: PropTypes.object
};
export default ValidationField;