import Vue from 'vue';
import isFunction from 'lodash/isFunction';
import { DISCLOSURE_DROPDOWN_ITEM_NAME, DISCLOSURE_DROPDOWN_GROUP_NAME } from './constants';

const itemValidator = item => {
  var _item$text;
  return (item === null || item === void 0 ? void 0 : (_item$text = item.text) === null || _item$text === void 0 ? void 0 : _item$text.length) > 0 && !Array.isArray(item === null || item === void 0 ? void 0 : item.items);
};
const isItem = item => Boolean(item) && itemValidator(item);
const isGroup = group => Boolean(group) && Array.isArray(group.items) && Boolean(group.items.length) &&
// eslint-disable-next-line unicorn/no-array-callback-reference
group.items.every(isItem);

// eslint-disable-next-line unicorn/no-array-callback-reference
const itemsValidator = items => items.every(isItem) || items.every(isGroup);
const isListItem = tag => ['gl-disclosure-dropdown-group', 'gl-disclosure-dropdown-item', 'li'].includes(tag);
const isValidSlotTagVue2 = vNode => {
  var _vNode$componentOptio, _vNode$componentOptio2, _vNode$componentOptio3, _vNode$componentOptio4;
  if (!vNode) return false;
  const tag = ((_vNode$componentOptio = vNode.componentOptions) === null || _vNode$componentOptio === void 0 ? void 0 : _vNode$componentOptio.tag) || vNode.tag;
  if (isListItem(tag)) return true;
  const componentName = (_vNode$componentOptio2 = vNode.componentOptions) === null || _vNode$componentOptio2 === void 0 ? void 0 : (_vNode$componentOptio3 = _vNode$componentOptio2.Ctor) === null || _vNode$componentOptio3 === void 0 ? void 0 : (_vNode$componentOptio4 = _vNode$componentOptio3.options) === null || _vNode$componentOptio4 === void 0 ? void 0 : _vNode$componentOptio4.name;
  return [DISCLOSURE_DROPDOWN_ITEM_NAME, DISCLOSURE_DROPDOWN_GROUP_NAME].includes(componentName);
};
const isValidSlotTagVue3 = vNode => {
  var _vNode$type;
  if (!vNode) return false;
  return [DISCLOSURE_DROPDOWN_ITEM_NAME, DISCLOSURE_DROPDOWN_GROUP_NAME].includes((_vNode$type = vNode.type) === null || _vNode$type === void 0 ? void 0 : _vNode$type.name) || vNode.type === 'li';
};
const isSkippableVue2 = vNode => {
  if (!vNode) return true;
  if (vNode.isComment) return true;
  if (!vNode.tag && typeof vNode.text === 'string' && !vNode.text.trim()) return true;
  return false;
};
const hasOnlyListItemsVue2 = defaultSlot => {
  const nodes = defaultSlot();
  if (!Array.isArray(nodes)) {
    return false;
  }
  const candidateNodes = nodes.filter(vNode => !isSkippableVue2(vNode));
  if (candidateNodes.length === 0) return true;
  return candidateNodes.every(vNode => isValidSlotTagVue2(vNode));
};
const isSkippableVue3 = vNode => {
  var _vNode$children;
  if (!vNode) return true;
  if (vNode.type === Vue.Comment) return true;
  if (vNode.type === Vue.Text && !((_vNode$children = vNode.children) !== null && _vNode$children !== void 0 && _vNode$children.trim())) return true;
  if (vNode.type === Vue.Fragment && (!vNode.children || vNode.children.length === 0)) return true;
  return false;
};
const validateNodesRecursiveVue3 = nodes => {
  if (!Array.isArray(nodes) || nodes.length === 0) return true;
  const candidateNodes = nodes.filter(vNode => !isSkippableVue3(vNode));
  if (candidateNodes.length === 0) return true;
  return candidateNodes.every(vNode => {
    if (isValidSlotTagVue3(vNode)) return true;
    if (vNode.type === Vue.Fragment && Array.isArray(vNode.children)) {
      return validateNodesRecursiveVue3(vNode.children);
    }
    return false;
  });
};
const hasOnlyListItemsVue3 = defaultSlot => {
  const nodes = defaultSlot();
  const fragment = nodes.find(node => Array.isArray(node.children) && node.children.length);
  const targetNodes = fragment ? fragment.children : nodes;
  return validateNodesRecursiveVue3(targetNodes);
};
const hasOnlyListItems = defaultSlot => {
  if (!isFunction(defaultSlot)) {
    return false;
  }
  if (Vue.version.startsWith('3')) {
    return hasOnlyListItemsVue3(defaultSlot);
  }
  return hasOnlyListItemsVue2(defaultSlot);
};

export { hasOnlyListItems, isGroup, isItem, itemsValidator };
