import { __assign, __extends, __rest } from "tslib";
import { Balloon, Button, CascaderSelect, Checkbox, DatePicker, Field, Form, Icon, Input, NumberPicker, Radio, Range, Select, Switch, TreeSelect, Upload } from '@alicloud/console-components';
import classnames from 'classnames';
import React, { Component } from 'react';
var mapper = {
    text: 'div',
    input: Input,
    select: Select,
    radioGroup: Radio.Group,
    checkboxGroup: Checkbox.Group,
    datePicker: DatePicker,
    numberPicker: NumberPicker,
    switch: Switch,
    range: Range,
    upload: Upload,
    combobox: Select,
    textarea: Input.TextArea,
    cascaderSelect: CascaderSelect,
    treeSelect: TreeSelect
};
;
;
var IotForm = /** @class */ (function (_super) {
    __extends(IotForm, _super);
    function IotForm(props) {
        var _this = _super.call(this, props) || this;
        _this.helpLabel = function (label, tips) {
            if (!label || label === "") {
                return null;
            }
            else {
                return (React.createElement("span", null,
                    label,
                    tips ? (React.createElement(Balloon, { autoFocus: false, type: "primary", align: "t", trigger: React.createElement(Icon, { type: 'help', className: "lp-form-tip-icon", size: "xs" }), closable: false }, tips)) : null));
            }
            ;
        };
        _this.field = props.field || new Field(_this, props.fieldOptions);
        _this.state = {
            source: props.source || []
        };
        return _this;
    }
    IotForm.getDerivedStateFromProps = function (nextProps) {
        if (nextProps.source) {
            return { source: nextProps.source };
        }
        return null;
    };
    IotForm.prototype.componentDidMount = function () {
        if (this.props.orgData) {
            this.field.setValues(this.props.orgData);
        }
    };
    IotForm.prototype.render = function () {
        var _a = this.props, field = _a.field, fieldOptions = _a.fieldOptions, className = _a.className, handleSubmit = _a.handleSubmit, handleReset = _a.handleReset, handleSubmitError = _a.handleSubmitError, localButtons = _a.localButtons, labelAlign = _a.labelAlign, orgData = _a.orgData, isNest = _a.isNest, allStart = _a.allStart, nest = _a.nest, footer = _a.footer, noSplitLine = _a.noSplitLine, footerAligin = _a.footerAligin, rest = __rest(_a, ["field", "fieldOptions", "className", "handleSubmit", "handleReset", "handleSubmitError", "localButtons", "labelAlign", "orgData", "isNest", "allStart", "nest", "footer", "noSplitLine", "footerAligin"]);
        var source = this.state.source;
        var content = this.pushFormItems(source, allStart);
        return (React.createElement(Form, __assign({ labelAlign: labelAlign, className: classnames('lp-form', { "lp-form-nest": isNest !== undefined ? isNest : nest }, className), field: this.field }, rest),
            content,
            footer === false ? null : React.createElement("div", { className: classnames('footer', { "lp-form-footer-nest": isNest !== undefined ? isNest : nest }, { "lp-form-footer-left": footerAligin === "left" }, { "lp-footer-noLine": noSplitLine }, className) }, this.renderButtons(localButtons, handleSubmitError, handleSubmit, handleReset))));
    };
    IotForm.prototype.renderButtons = function (localButtons, handleSubmitError, handleSubmit, handleReset) {
        var buttons = [];
        if (localButtons) {
            return localButtons.map(function (item, index) {
                switch (item.type) {
                    case 'submit':
                        return (React.createElement(Form.Submit, __assign({ key: 'lp_form_submit_Button_local' + index }, item.props, { validate: item.validate ? item.validate : true, type: "primary", onClick: function (v, e) {
                                e ? item.handleSubmitError && item.handleSubmitError(e) : item.handleIt && item.handleIt(v);
                            } }), item.name));
                    case 'reset':
                        return (React.createElement(Form.Reset, __assign({}, item.props, { key: 'lp_form_submit_Button_local' + index, onClick: item.handleIt }), item.name));
                    case 'normal':
                        return (React.createElement(Button, __assign({ key: 'lp_form_submit_Button_local' + index }, item.props, { onClick: item.handleIt }), item.name));
                    default:
                        return null;
                }
            });
        }
        else {
            buttons.push(React.createElement(Form.Submit, { key: "lp_form_submit_Button", validate: true, type: "primary", onClick: function (v, e) {
                    e
                        ? handleSubmitError && handleSubmitError(e)
                        : handleSubmit && handleSubmit(v);
                } }, "\u5B8C\u6210"));
            buttons.push(React.createElement(Form.Reset, { key: "lp_form_reset_Button", onClick: handleReset }, "\u91CD\u7F6E"));
        }
        return buttons;
    };
    IotForm.prototype.pushFormItems = function (source, allStart) {
        var _this = this;
        //如果每个选项都是必填，那么label上不出现*
        var requireCount = 0;
        var allRequire = false;
        if (!allStart) {
            for (var _i = 0, source_1 = source; _i < source_1.length; _i++) {
                var i = source_1[_i];
                if (i.required || i.type === 'switch') {
                    requireCount++;
                }
            }
            if (requireCount == source.length) {
                allRequire = true;
            }
        }
        return source.map(function (item, index) {
            return (React.createElement("div", { className: (index === source.length - 1) ? "formGridRow lastOne" : "formGridRow", key: 'lp_form_row' + index }, Array.isArray(item)
                ? (function () {
                    return item.map(function (c, i) {
                        return (React.createElement("div", { className: "GridCol", key: 'lp_form_col' + i }, _this.renderFormItem(c, allRequire, true)));
                    });
                })()
                : (function () {
                    return _this.renderFormItem(item, allRequire, undefined);
                })()));
        });
    };
    IotForm.prototype.renderFormItem = function (item, allRequire, fillOver) {
        var _this = this;
        var type = item.type, name = item.name, label = item.label, _a = item.props, props = _a === void 0 ? {} : _a, _b = item.options, options = _b === void 0 ? {} : _b, template = item.template, _c = item.formItemProps, formItemProps = _c === void 0 ? {} : _c, tips = item.tips, required = item.required;
        //如果是必填自动添加规则
        if (required) {
            if (options.rules) {
                if (Array.isArray(options.rules)) {
                    options.rules.push({
                        required: true,
                        message: '抱歉,' + label + '不能为空值'
                    });
                }
                else {
                    var temprRules = [];
                    temprRules.push(options.rules);
                    temprRules.push({
                        required: true,
                        message: '抱歉,' + label + '不能为空值'
                    });
                    options.rules = temprRules;
                }
            }
            else {
                options['rules'] = {
                    required: true,
                    message: '抱歉,' + label + '不能为空值'
                };
            }
        }
        var fieldProps = this.field.init(name, options);
        var itemType = template ? 'custom' : type;
        var itemProps = __assign(__assign({}, fieldProps), props);
        var component = {
            class: function () { }
        };
        //使checkbox，radio 等垂直排部
        if (itemProps.vertical) {
            if (itemProps["className"]) {
                itemProps["className"] = itemProps["className"] + " vertical";
            }
            else {
                itemProps["className"] = "vertical";
            }
        }
        delete itemProps.vertical;
        this.updateItemStyles(itemType, itemProps, fillOver);
        var componentClass = mapper[itemType];
        if (itemType === 'custom') {
            if (!(template.prototype instanceof React.Component)) {
                delete itemProps.ref;
            }
            itemProps.setValue = function (value) { return _this.field.setValue(name, value); };
            if (typeof template === 'function') {
                var RenderComponent = template;
                return React.createElement(Form.Item, __assign({ key: name, label: this.helpLabel(label, tips), required: allRequire ? false : required, help: this.renderHelp(name) }, formItemProps),
                    React.createElement(RenderComponent, __assign({}, itemProps)));
            }
            else {
                return React.createElement(Form.Item, __assign({ key: name, label: this.helpLabel(label, tips), required: allRequire ? false : required, help: this.renderHelp(name) }, formItemProps), template);
            }
        }
        else {
            if (componentClass) {
                component.class = componentClass;
                if (itemType === 'combobox') {
                    itemProps['mode'] = 'tag';
                    itemProps['hasArrow'] = false;
                }
            }
            else {
                console.log("\u4E0D\u652F\u6301" + itemType + "\u8868\u5355\u7C7B\u578B. Sorry, " + itemType + " is not supported by current version's form.");
            }
            var Component_ = component.class;
            return (React.createElement(Form.Item, __assign({ key: name, label: this.helpLabel(label, tips), required: allRequire ? false : required, help: this.renderHelp(name) }, formItemProps),
                React.createElement(Component_, __assign({}, itemProps))));
        }
    };
    IotForm.prototype.updateItemStyles = function (type, props, fillOver) {
        var typesWithNoWidth = [
            'radioGroup',
            'checkboxGroup',
            'numberPicker',
            'switch',
            'upload'
        ];
        if (fillOver) {
            props.style = __assign({ width: '100%' }, props.style);
        }
        else if (!typesWithNoWidth.includes(type)) {
            props.style = __assign({ width: 280 }, props.style);
        }
    };
    IotForm.prototype.renderHelp = function (name) {
        var type = this.field.getState(name);
        var errors = this.field.getError(name) || [];
        if (type === 'validating') {
            return '校验中...';
        }
        else if (errors.length > 0) {
            return errors[0];
        }
        return '';
    };
    return IotForm;
}(Component));
IotForm.defaultProps = {
    source: [],
    labelAlign: 'top',
    autoComplete: "off",
    allStart: true,
    fieldOptions: {
        forceUpdate: true,
        autoUnmount: true
    },
    footer: true
};
export default IotForm;
