/**
 * ldesign v0.2.14
 * (c) 2022/11/2 16:16 built by swimly
 * @license MIT
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var Vue = require('vue');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue);

const defaultModel = {
  prop: "value",
  event: "input"
};
function toCamel(str) {
  return str.replace(/-([a-z])/gi, (m, letter) => letter.toUpperCase());
}
function getPropOptionMap(props) {
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  const propOptionMap = {};
  const {
    model
  } = options;
  function parseProp(propOption) {
    const {
      name: propName,
      ...others
    } = propOption;
    const camelName = propName.replace(/^[a-z]/, letter => letter.toUpperCase());
    const defaultName = `default${camelName}`;
    const dataName = `data${camelName}`;
    let events = [];
    if (propOption.event) events = events.concat(propOption.event);else if (model.prop === propName) events = events.concat(model.event);else events = events.concat(`update:${propName}`);
    return {
      events,
      defaultName,
      dataName,
      ...others
    };
  }
  props.forEach(prop => {
    const defaultOption = {
      alias: []
    };
    let propOption;
    if (typeof prop === "string") propOption = {
      ...defaultOption,
      name: prop
    };else propOption = {
      ...defaultOption,
      ...prop
    };
    propOptionMap[propOption.name] = parseProp(propOption);
  });
  return propOptionMap;
}
function mapProps (props) {
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  function mapProps(componentConstructor) {
    const component = componentConstructor.prototype ? componentConstructor.prototype.constructor.options : componentConstructor;
    const model = options.model || defaultModel;
    const propOptionMap = getPropOptionMap(props, {
      model
    });
    const defineProps = {
      ...component.props
    };
    const defineWatches = {};
    let defineEvents = [];
    const defineMethods = {};
    const propsKeys = Object.keys(component.props);
    const camelPropsKeys = propsKeys.map(key => toCamel(key));
    Object.keys(propOptionMap).forEach(propName => {
      const {
        events,
        alias,
        defaultName,
        dataName
      } = propOptionMap[propName];
      defineProps[propName] = component.props[propName];
      defineProps[defaultName] = component.props[defaultName];
      if (alias) {
        alias.forEach(prop => {
          defineProps[prop] = defineProps[propName];
        });
      }
      defineEvents = defineEvents.concat(events);
      defineWatches[defaultName] = {
        handler(v) {
          if (defaultName in this.$vnode.componentOptions.propsData && !(propName in this.$vnode.componentOptions.propsData)) this.$data[dataName] = v;
        },
        immediate: true
      };
      alias.forEach(aliasItem => {
        defineWatches[aliasItem] = {
          handler(v) {
            if (aliasItem in this.$vnode.componentOptions.propsData && !(propName in this.$vnode.componentOptions.propsData)) this.$data[dataName] = v;
          },
          immediate: true
        };
      });
      defineWatches[propName] = {
        handler(v) {
          if (propName in this.$vnode.componentOptions.propsData) this.$data[dataName] = v;
        },
        immediate: true
      };
    });
    if (component.methods) {
      Object.keys(component.methods).forEach(key => {
        defineMethods[key] = function () {
          if (this.$refs.component) return this.$refs.component[key](...arguments);
        };
      });
    }
    const {
      name
    } = component;
    return Vue__default["default"].extend({
      name: `${name}-mapprops`,
      inheritAttrs: false,
      model: {
        prop: model.prop,
        event: Array.isArray(model.event) ? model.event[0] : model.event
      },
      props: {
        ...defineProps
      },
      data() {
        const data = {};
        Object.keys(propOptionMap).forEach(propName => {
          const {
            dataName
          } = propOptionMap[propName];
          data[dataName] = void 0;
        });
        return {
          ...data
        };
      },
      computed: {
        _listeners() {
          var _this = this;
          const others = {};
          Object.keys(this.$listeners).forEach(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(event, ...args);
              };
            }
          });
          return others;
        }
      },
      watch: defineWatches,
      methods: {
        updateData(propName, v) {
          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(event => {
            this.$emit(event, v, ...args);
          });
          if (!(propName in this.$vnode.componentOptions.propsData)) {
            this[propOptionMap[propName].dataName] = v;
            return true;
          }
        },
        ...defineMethods
      },
      render(h) {
        var _this2 = this;
        const propMap = {};
        const handlerMap = {};
        Object.keys(propOptionMap).forEach(propName => {
          const {
            dataName,
            events
          } = propOptionMap[propName];
          if (propName in this.$vnode.componentOptions.propsData || typeof this[dataName] !== "undefined") propMap[propName] = this[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 _this2.updateData(propName, v, ...args);
          };
        });
        const attrs = {};
        Object.keys(this.$attrs).forEach(attrName => {
          const camelAttrKey = toCamel(attrName);
          if (!camelPropsKeys.includes(camelAttrKey)) attrs[attrName] = this.$attrs[attrName];
        });
        return h(component, {
          props: {
            ...this.$props,
            ...propMap
          },
          attrs: {
            ...attrs
          },
          on: {
            ...this._listeners,
            ...handlerMap
          },
          scopedSlots: {
            ...this.$scopedSlots
          },
          ref: "component"
        });
      }
    });
  }
  return mapProps;
}

exports["default"] = mapProps;
//# sourceMappingURL=map-props.js.map
