"use strict";

var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _ui = require("../../ui");
var _vn = require("../../ui/src/vn");
var _log = require("../../ui/src/log");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var _createComponentLog = (0, _log.createComponentLog)('form'),
  errLog = _createComponentLog.errLog;
var componentDefaultModelProp = 'value';
/**
 * 已废弃
 * @deprecated
 */
function getOldComponentName(name) {
  return "vxe-".concat("".concat(name || '').replace('$', ''));
}
/**
 * 已废弃
 * @deprecated
 */
function getOldComponent(_ref) {
  var name = _ref.name;
  return getOldComponentName(name);
}
function getDefaultComponent(_ref2) {
  var name = _ref2.name;
  return (0, _ui.getComponent)(name) || name;
}
function getNativeAttrs(renderOpts) {
  var name = renderOpts.name,
    attrs = renderOpts.attrs;
  if (name === 'input') {
    attrs = Object.assign({
      type: 'text'
    }, attrs);
  }
  return attrs;
}
function getComponentFormItemProps(renderOpts, params, value, defaultProps) {
  return _xeUtils.default.assign({}, defaultProps, renderOpts.props, _defineProperty({}, componentDefaultModelProp, value));
}
/**
 * 原生事件处理
 * @param renderOpts
 * @param params
 * @param modelFunc
 * @param changeFunc
 */
function getElementOns(renderOpts, params, modelFunc, changeFunc) {
  var events = renderOpts.events;
  var modelEvent = (0, _vn.getModelEvent)(renderOpts);
  var changeEvent = (0, _vn.getChangeEvent)(renderOpts);
  var isSameEvent = changeEvent === modelEvent;
  var ons = {};
  if (events) {
    _xeUtils.default.objectEach(events, function (func, key) {
      ons[(0, _vn.getOnName)(key)] = function () {
        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }
        func.apply(void 0, [params].concat(args));
      };
    });
  }
  if (modelFunc) {
    ons[(0, _vn.getOnName)(modelEvent)] = function (targetEvnt) {
      modelFunc(targetEvnt);
      if (isSameEvent && changeFunc) {
        changeFunc(targetEvnt);
      }
      if (events && events[modelEvent]) {
        events[modelEvent](params, targetEvnt);
      }
    };
  }
  if (!isSameEvent && changeFunc) {
    ons[(0, _vn.getOnName)(changeEvent)] = function () {
      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }
      changeFunc.apply(void 0, args);
      if (events && events[changeEvent]) {
        events[changeEvent].apply(events, [params].concat(args));
      }
    };
  }
  return ons;
}
/**
 * 组件事件处理
 * @param renderOpts
 * @param params
 * @param modelFunc
 * @param changeFunc
 */
function getComponentOns(renderOpts, params, eFns, eventOns) {
  var events = renderOpts.events;
  var _ref3 = eFns || {},
    modelFunc = _ref3.model,
    changeFunc = _ref3.change;
  var modelEvent = (0, _vn.getModelEvent)(renderOpts);
  var changeEvent = (0, _vn.getChangeEvent)(renderOpts);
  var ons = {};
  _xeUtils.default.objectEach(events, function (func, key) {
    ons[(0, _vn.getOnName)(key)] = function () {
      if (!_xeUtils.default.isFunction(func)) {
        errLog('vxe.error.errFunc', [func]);
      }
      for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
        args[_key3] = arguments[_key3];
      }
      func.apply(void 0, [params].concat(args));
    };
  });
  if (modelFunc) {
    ons[(0, _vn.getOnName)(modelEvent)] = function (targetEvnt) {
      modelFunc(targetEvnt);
      if (events && events[modelEvent]) {
        events[modelEvent](params, targetEvnt);
      }
    };
  }
  if (changeFunc) {
    ons[(0, _vn.getOnName)(changeEvent)] = function () {
      for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
        args[_key4] = arguments[_key4];
      }
      changeFunc.apply(void 0, args);
      if (events && events[changeEvent]) {
        events[changeEvent].apply(events, [params].concat(args));
      }
    };
  }
  return eventOns ? Object.assign(ons, eventOns) : ons;
}
function getItemOns(renderOpts, params) {
  var $form = params.$form,
    data = params.data,
    field = params.field;
  return getComponentOns(renderOpts, params, {
    model: function model(value) {
      // 处理 model 值双向绑定
      _xeUtils.default.set(data, field, value);
    },
    change: function change() {
      // 处理 change 事件相关逻辑
      $form.updateStatus(params);
      if (renderOpts.changeToSubmit) {
        $form.handleSubmitEvent(new Event('change'));
      }
    }
  });
}
function getNativeItemOns(renderOpts, params) {
  var $form = params.$form,
    data = params.data,
    field = params.field;
  return getElementOns(renderOpts, params, function (evnt) {
    // 处理 model 值双向绑定
    var itemValue = evnt.target.value;
    _xeUtils.default.set(data, field, itemValue);
  }, function () {
    // 处理 change 事件相关逻辑
    $form.updateStatus(params);
  });
}
function renderNativeOptgroup(h, renderOpts, params, renderOptionsMethods) {
  var optionGroups = renderOpts.optionGroups,
    _renderOpts$optionGro = renderOpts.optionGroupProps,
    optionGroupProps = _renderOpts$optionGro === void 0 ? {} : _renderOpts$optionGro;
  var groupOptions = optionGroupProps.options || 'options';
  var groupLabel = optionGroupProps.label || 'label';
  if (optionGroups) {
    return optionGroups.map(function (group, gIndex) {
      return h('optgroup', {
        key: gIndex,
        attrs: {
          label: group[groupLabel]
        }
      }, renderOptionsMethods(group[groupOptions], renderOpts, params));
    });
  }
  return [];
}
/**
 * 渲染表单-项
 * 用于渲染原生的标签
 */
function nativeItemRender(h, renderOpts, params) {
  var data = params.data,
    field = params.field;
  var name = renderOpts.name;
  var attrs = getNativeAttrs(renderOpts);
  var itemValue = _xeUtils.default.get(data, field);
  return [h("".concat(name), {
    class: "vxe-default-".concat(name),
    attrs: attrs,
    domProps: {
      value: attrs && name === 'input' && (attrs.type === 'submit' || attrs.type === 'reset') ? null : itemValue
    },
    on: getNativeItemOns(renderOpts, params)
  })];
}
function defaultItemRender(h, renderOpts, params) {
  var data = params.data,
    field = params.field;
  var itemValue = _xeUtils.default.get(data, field);
  return [h(getDefaultComponent(renderOpts), {
    props: getComponentFormItemProps(renderOpts, params, itemValue),
    on: getItemOns(renderOpts, params)
  })];
}
/**
 * 已废弃
 * @deprecated
 */
function oldItemRender(h, renderOpts, params) {
  var data = params.data,
    field = params.field;
  var itemValue = _xeUtils.default.get(data, field);
  return [h(getOldComponent(renderOpts), {
    props: getComponentFormItemProps(renderOpts, params, itemValue),
    on: getItemOns(renderOpts, params)
  })];
}
/**
 * 已废弃
 * @deprecated
 */
function oldButtonItemRender(h, renderOpts, params) {
  return [h('vxe-button', {
    props: getComponentFormItemProps(renderOpts, params, null),
    on: getComponentOns(renderOpts, params)
  })];
}
/**
 * 已废弃
 * @deprecated
 */
function oldButtonsItemRender(h, renderOpts, params) {
  var children = renderOpts.children;
  return children ? children.map(function (childRenderOpts) {
    return oldButtonItemRender(h, childRenderOpts, params)[0];
  }) : [];
}
/**
 * 渲染原生的 select 标签
 */
function renderNativeFormOptions(h, options, renderOpts, params) {
  var data = params.data,
    field = params.field;
  var _renderOpts$optionPro = renderOpts.optionProps,
    optionProps = _renderOpts$optionPro === void 0 ? {} : _renderOpts$optionPro;
  var labelProp = optionProps.label || 'label';
  var valueProp = optionProps.value || 'value';
  var disabledProp = optionProps.disabled || 'disabled';
  var cellValue = _xeUtils.default.get(data, field);
  if (options) {
    return options.map(function (item, oIndex) {
      return h('option', {
        key: oIndex,
        props: {
          value: item[valueProp],
          disabled: item[disabledProp],
          /* eslint-disable eqeqeq */
          selected: item[valueProp] == cellValue
        }
      }, item[labelProp]);
    });
  }
  return [];
}
/**
 * 渲染表单-项
 */
function defaultFormItemRender(h, renderOpts, params) {
  var data = params.data,
    field = params.field;
  var itemValue = _xeUtils.default.get(data, field);
  return [h(getDefaultComponent(renderOpts), {
    props: getComponentFormItemProps(renderOpts, params, itemValue),
    on: getItemOns(renderOpts, params)
  })];
}
function formItemRadioAndCheckboxRender(h, renderOpts, params) {
  var options = renderOpts.options,
    optionProps = renderOpts.optionProps;
  var data = params.data,
    field = params.field;
  var itemValue = _xeUtils.default.get(data, field);
  return [h(getDefaultComponent(renderOpts), {
    props: Object.assign({
      options: options,
      optionProps: optionProps
    }, getComponentFormItemProps(renderOpts, params, itemValue)),
    on: getItemOns(renderOpts, params)
  })];
}
/**
 * 已废弃
 * @deprecated
 */
function oldFormItemRadioAndCheckboxRender(h, renderOpts, params) {
  var name = renderOpts.name,
    options = renderOpts.options,
    _renderOpts$optionPro2 = renderOpts.optionProps,
    optionProps = _renderOpts$optionPro2 === void 0 ? {} : _renderOpts$optionPro2;
  var data = params.data,
    field = params.field;
  var labelProp = optionProps.label || 'label';
  var valueProp = optionProps.value || 'value';
  var disabledProp = optionProps.disabled || 'disabled';
  var itemValue = _xeUtils.default.get(data, field);
  var compName = getOldComponentName(name);
  // 如果是分组
  if (options) {
    return [h("".concat(compName, "-group"), {
      props: getComponentFormItemProps(renderOpts, params, itemValue),
      on: getItemOns(renderOpts, params),
      scopedSlots: {
        default: function _default() {
          return options.map(function (item, index) {
            return h(compName, {
              key: index,
              props: {
                label: item[valueProp],
                content: item[labelProp],
                disabled: item[disabledProp]
              }
            });
          });
        }
      }
    })];
  }
  return [h(compName, {
    props: getComponentFormItemProps(renderOpts, params, itemValue),
    on: getItemOns(renderOpts, params)
  })];
}
/**
 * 表单 - 渲染器
 */
_ui.renderer.mixin({
  input: {
    formItemAutoFocus: true,
    renderFormItemContent: nativeItemRender
  },
  textarea: {
    formItemAutoFocus: true,
    renderFormItemContent: nativeItemRender
  },
  select: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      return [h('select', {
        class: 'vxe-default-select',
        attrs: Object.assign({}, getNativeAttrs(renderOpts)),
        on: getNativeItemOns(renderOpts, params)
      }, renderOpts.optionGroups ? renderNativeOptgroup(h, renderOpts, params, renderNativeFormOptions) : renderNativeFormOptions(h, renderOpts.options, renderOpts, params))];
    }
  },
  VxeInput: {
    formItemAutoFocus: true,
    renderFormItemContent: defaultItemRender
  },
  VxeNumberInput: {
    formItemAutoFocus: true,
    renderFormItemContent: defaultItemRender
  },
  VxePasswordInput: {
    formItemAutoFocus: true,
    renderFormItemContent: defaultItemRender
  },
  VxeTextarea: {
    formItemAutoFocus: true,
    renderFormItemContent: defaultItemRender
  },
  VxeDatePicker: {
    formItemAutoFocus: true,
    renderFormItemContent: defaultItemRender
  },
  VxeDateRangePicker: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var startField = renderOpts.startField,
        endField = renderOpts.endField;
      var $form = params.$form,
        data = params.data,
        field = params.field;
      var itemValue = _xeUtils.default.get(data, field);
      var seProps = {};
      var seOs = {};
      if (startField && endField) {
        seProps.startValue = _xeUtils.default.get(data, startField);
        seProps.endValue = _xeUtils.default.get(data, endField);
        seOs['update:startValue'] = function (value) {
          if (startField) {
            _xeUtils.default.set(data, startField, value);
          }
        };
        seOs['update:endValue'] = function (value) {
          if (endField) {
            _xeUtils.default.set(data, endField, value);
          }
        };
      }
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, seProps),
        on: getComponentOns(renderOpts, params, {
          model: function model(value) {
            // 处理 model 值双向绑定
            _xeUtils.default.set(data, field, value);
          },
          change: function change(_ref4) {
            var $event = _ref4.$event,
              isFinish = _ref4.isFinish;
            // 处理 change 事件相关逻辑
            $form.updateStatus(params);
            if (renderOpts.changeToSubmit && isFinish) {
              $form.handleSubmitEvent($event);
            }
          }
        }, seOs)
      })];
    }
  },
  VxeButton: {
    renderFormItemContent: defaultFormItemRender
  },
  VxeButtonGroup: {
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var options = renderOpts.options;
      var data = params.data,
        field = params.field;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: Object.assign({
          options: options
        }, getComponentFormItemProps(renderOpts, params, itemValue)),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeSelect: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options,
        optionProps = renderOpts.optionProps,
        optionGroups = renderOpts.optionGroups,
        optionGroupProps = renderOpts.optionGroupProps;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          options: options,
          optionProps: optionProps,
          optionGroups: optionGroups,
          optionGroupProps: optionGroupProps
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeTreeSelect: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options,
        optionProps = renderOpts.optionProps;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          options: options,
          optionProps: optionProps
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeCascader: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options,
        optionProps = renderOpts.optionProps;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          options: options,
          optionProps: optionProps
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeTableSelect: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options,
        optionProps = renderOpts.optionProps;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          options: options,
          optionProps: optionProps
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeColorPicker: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          colors: options
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeIconPicker: {
    formItemAutoFocus: true,
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          icons: options
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeRadio: {
    renderFormItemContent: defaultFormItemRender
  },
  VxeRadioGroup: {
    renderFormItemContent: formItemRadioAndCheckboxRender
  },
  VxeCheckbox: {
    renderFormItemContent: defaultFormItemRender
  },
  VxeCheckboxGroup: {
    renderFormItemContent: formItemRadioAndCheckboxRender
  },
  VxeSwitch: {
    renderFormItemContent: defaultItemRender
  },
  VxeRate: {
    renderFormItemContent: defaultItemRender
  },
  VxeSlider: {
    renderFormItemContent: defaultItemRender
  },
  VxeImage: {
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var props = renderOpts.props;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: Object.assign(Object.assign({}, props), {
          src: itemValue
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeImageGroup: {
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var props = renderOpts.props;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getDefaultComponent(renderOpts), {
        props: Object.assign(Object.assign({}, props), {
          urlList: itemValue
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  VxeUpload: {
    renderFormItemContent: defaultItemRender
  },
  // 以下已废弃
  $input: {
    formItemAutoFocus: 'input',
    renderFormItemContent: oldItemRender
  },
  $textarea: {
    formItemAutoFocus: 'textarea',
    renderFormItemContent: oldItemRender
  },
  $button: {
    renderFormItemContent: oldButtonItemRender
  },
  $buttons: {
    renderFormItemContent: oldButtonsItemRender
  },
  $select: {
    formItemAutoFocus: 'input',
    renderFormItemContent: function renderFormItemContent(h, renderOpts, params) {
      var data = params.data,
        field = params.field;
      var options = renderOpts.options,
        optionProps = renderOpts.optionProps,
        optionGroups = renderOpts.optionGroups,
        optionGroupProps = renderOpts.optionGroupProps;
      var itemValue = _xeUtils.default.get(data, field);
      return [h(getOldComponent(renderOpts), {
        props: getComponentFormItemProps(renderOpts, params, itemValue, {
          options: options,
          optionProps: optionProps,
          optionGroups: optionGroups,
          optionGroupProps: optionGroupProps
        }),
        on: getItemOns(renderOpts, params)
      })];
    }
  },
  $radio: {
    renderFormItemContent: oldFormItemRadioAndCheckboxRender
  },
  $checkbox: {
    renderFormItemContent: oldFormItemRadioAndCheckboxRender
  },
  $switch: {
    renderFormItemContent: oldItemRender
  }
  // 以上已废弃
});