import { isVNode, Fragment, Comment, Text, createTextVNode } from 'vue';
import { isOn } from '@vue/shared';
import isValid from '../isValid';
export const splitAttrs = attrs => {
  const allAttrs = Object.keys(attrs);
  const eventAttrs = {};
  const onEvents = {};
  const extraAttrs = {};

  for (let i = 0, l = allAttrs.length; i < l; i++) {
    const key = allAttrs[i];

    if (isOn(key)) {
      eventAttrs[key[2].toLowerCase() + key.slice(3)] = attrs[key];
      onEvents[key] = attrs[key];
    } else {
      extraAttrs[key] = attrs[key];
    }
  }

  return {
    onEvents,
    events: eventAttrs,
    extraAttrs
  };
};
export const findDOMNode = instance => {
  var _instance$vnode;

  let node = (instance === null || instance === void 0 ? void 0 : (_instance$vnode = instance.vnode) === null || _instance$vnode === void 0 ? void 0 : _instance$vnode.el) || (instance === null || instance === void 0 ? void 0 : instance.$el) || instance;

  while (node && !node.tagName) node = node.nextSibling;

  return node;
};
export function isEmptyElement(c) {
  return c.type === Comment || c.type === Fragment && c.children.length === 0 || c.type === Text && c.children.trim() === '';
}
export function filterEmpty(children = []) {
  const res = [];
  children.forEach(child => {
    if (Array.isArray(child)) {
      res.push(...child);
    } else if (child.type === Fragment) {
      res.push(...child.children);
    } else {
      res.push(child);
    }
  });
  return res.filter(c => !isEmptyElement(c));
}
export const flattenChildren = (children, filterEmpty = true) => {
  const temp = Array.isArray(children) ? children : [children];
  const res = [];
  temp.forEach(child => {
    if (Array.isArray(child)) {
      res.push(...flattenChildren(child, filterEmpty));
    } else if (child && child.type === Fragment) {
      res.push(...flattenChildren(child.children, filterEmpty));
    } else if (child && isVNode(child)) {
      if (filterEmpty && !isEmptyElement(child)) {
        res.push(child);
      } else if (!filterEmpty) {
        res.push(child);
      }
    } else if (isValid(child)) {
      res.push(child);
    }
  });
  return res;
};
export const getSlot = (self, name = 'default', options = {}) => {
  let res;

  if (typeof self === 'function') {
    res = self(options);
  } else {
    var _name, _ref;

    res = (_name = (_ref = self.$slots || self.slots || self)[name]) === null || _name === void 0 ? void 0 : _name.call(_ref, options);
  }

  return flattenChildren(res);
};
export const getComponent = (ins, prop = 'default', opts = ins) => {
  let props = ins.$props || ins.props || ins,
      slots = ins.$slots || ins.slots;
  return render(props[prop] || slots[prop], opts);
};
export const render = (content, ...args) => {
  if (typeof content === 'function') {
    return content(...args);
  } else if (typeof content === 'object' && content) {
    return content;
  } else if (isValid(content)) {
    return createTextVNode(String(content));
  } else {
    return undefined;
  }
};
export function noop() {}
export function isValidElement(element) {
  return isVNode(element) && typeof element.type !== 'symbol';
}
export function hasElemnt(element) {
  if (element == null) {
    return false;
  } else if (Array.isArray(element)) {
    return element.some(hasElemnt);
  } else {
    if (isVNode(element)) {
      if (typeof element.type === 'symbol') {
        return hasElemnt(element.children);
      } else {
        return true;
      }
    }

    return typeof element === 'string' || typeof element === 'number';
  }
}