/**
 * ldesign v0.4.6
 * (c) 2023 ldesign
 * @license MIT
 */

import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
import Vue from 'vue';

var _excluded = ["name"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var defaultModel = {
  prop: "value",
  event: "input"
};
function toCamel(str) {
  return str.replace(/-([a-z])/ig, function (m, letter) {
    return letter.toUpperCase();
  });
}
function getPropOptionMap(props) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var propOptionMap = {};
  var model = options.model;
  function parseProp(propOption) {
    var propName = propOption.name,
      others = _objectWithoutProperties(propOption, _excluded);
    var camelName = propName.replace(/^[a-z]/, function (letter) {
      return letter.toUpperCase();
    });
    var defaultName = "default".concat(camelName);
    var dataName = "data".concat(camelName);
    var events = [];
    if (propOption.event) events = events.concat(propOption.event);else if (model.prop === propName) events = events.concat(model.event);else events = events.concat("update:".concat(propName));
    return _objectSpread({
      events: events,
      defaultName: defaultName,
      dataName: dataName
    }, others);
  }
  props.forEach(function (prop) {
    var defaultOption = {
      alias: []
    };
    var propOption;
    if (typeof prop === "string") propOption = _objectSpread(_objectSpread({}, defaultOption), {}, {
      name: prop
    });else propOption = _objectSpread(_objectSpread({}, defaultOption), prop);
    propOptionMap[propOption.name] = parseProp(propOption);
  });
  return propOptionMap;
}
function mapProps (props) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  function mapProps(componentConstructor) {
    var component = componentConstructor.prototype ? componentConstructor.prototype.constructor.options : componentConstructor;
    var model = options.model || defaultModel;
    var propOptionMap = getPropOptionMap(props, {
      model: model
    });
    var defineProps = _objectSpread({}, component.props);
    var defineWatches = {};
    var defineEvents = [];
    var defineMethods = {};
    var propsKeys = Object.keys(component.props);
    var camelPropsKeys = propsKeys.map(function (key) {
      return toCamel(key);
    });
    Object.keys(propOptionMap).forEach(function (propName) {
      var _propOptionMap$propNa = propOptionMap[propName],
        events = _propOptionMap$propNa.events,
        alias = _propOptionMap$propNa.alias,
        defaultName = _propOptionMap$propNa.defaultName,
        dataName = _propOptionMap$propNa.dataName;
      defineProps[propName] = component.props[propName];
      defineProps[defaultName] = component.props[defaultName];
      if (alias) {
        alias.forEach(function (prop) {
          defineProps[prop] = defineProps[propName];
        });
      }
      defineEvents = defineEvents.concat(events);
      defineWatches[defaultName] = {
        handler: function handler(v) {
          if (defaultName in this.$vnode.componentOptions.propsData && !(propName in this.$vnode.componentOptions.propsData)) this.$data[dataName] = v;
        },
        immediate: true
      };
      alias.forEach(function (aliasItem) {
        defineWatches[aliasItem] = {
          handler: function handler(v) {
            if (aliasItem in this.$vnode.componentOptions.propsData && !(propName in this.$vnode.componentOptions.propsData)) this.$data[dataName] = v;
          },
          immediate: true
        };
      });
      defineWatches[propName] = {
        handler: function handler(v) {
          if (propName in this.$vnode.componentOptions.propsData) this.$data[dataName] = v;
        },
        immediate: true
      };
    });
    if (component.methods) {
      Object.keys(component.methods).forEach(function (key) {
        defineMethods[key] = function () {
          var _this$$refs$component;
          if (this.$refs.component) return (_this$$refs$component = this.$refs.component)[key].apply(_this$$refs$component, arguments);
        };
      });
    }
    var name = component.name;
    return Vue.extend({
      name: "".concat(name, "-mapprops"),
      inheritAttrs: false,
      model: {
        prop: model.prop,
        event: Array.isArray(model.event) ? model.event[0] : model.event
      },
      props: _objectSpread({}, defineProps),
      data: function data() {
        var data = {};
        Object.keys(propOptionMap).forEach(function (propName) {
          var dataName = propOptionMap[propName].dataName;
          data[dataName] = void 0;
        });
        return _objectSpread({}, data);
      },
      computed: {
        _listeners: function _listeners() {
          var _this = this;
          var others = {};
          Object.keys(this.$listeners).forEach(function (event) {
            if (!defineEvents.includes(event)) {
              others[event] = function () {
                for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
                  args[_key] = arguments[_key];
                }
                _this.$emit.apply(_this, [event].concat(args));
              };
            }
          });
          return others;
        }
      },
      watch: defineWatches,
      methods: _objectSpread({
        updateData: function updateData(propName, v) {
          var _this2 = this;
          for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
            args[_key2 - 2] = arguments[_key2];
          }
          propOptionMap[propName].events.forEach(function (event) {
            _this2.$emit.apply(_this2, [event, v].concat(args));
          });
          if (!(propName in this.$vnode.componentOptions.propsData)) {
            this[propOptionMap[propName].dataName] = v;
            return true;
          }
        }
      }, defineMethods),
      render: function render(h) {
        var _this3 = this;
        var propMap = {};
        var handlerMap = {};
        Object.keys(propOptionMap).forEach(function (propName) {
          var _propOptionMap$propNa2 = propOptionMap[propName],
            dataName = _propOptionMap$propNa2.dataName,
            events = _propOptionMap$propNa2.events;
          if (propName in _this3.$vnode.componentOptions.propsData || typeof _this3[dataName] !== "undefined") propMap[propName] = _this3[dataName];
          handlerMap[events[0]] = function (v) {
            for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
              args[_key3 - 1] = arguments[_key3];
            }
            return _this3.updateData.apply(_this3, [propName, v].concat(args));
          };
        });
        var attrs = {};
        Object.keys(this.$attrs).forEach(function (attrName) {
          var camelAttrKey = toCamel(attrName);
          if (!camelPropsKeys.includes(camelAttrKey)) attrs[attrName] = _this3.$attrs[attrName];
        });
        return h(component, {
          props: _objectSpread(_objectSpread({}, this.$props), propMap),
          attrs: _objectSpread({}, attrs),
          on: _objectSpread(_objectSpread({}, this._listeners), handlerMap),
          scopedSlots: _objectSpread({}, this.$scopedSlots),
          ref: "component"
        });
      }
    });
  }
  return mapProps;
}

export { mapProps as default };
//# sourceMappingURL=map-props.js.map
