import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _toArray from "@babel/runtime/helpers/toArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _isBoolean from "lodash/isBoolean";

/* eslint-disable */
import { endWidth } from "../util";
import { defaultTarget, formPlugins } from "../../config/pluginConfig";
import cloneDeep from 'lodash/cloneDeep';
import showError from "../error";
import { createTableRowCell, createText, createExpression } from "../../editor/utils";
import { tagNameMaps, deleteSpaceAndEnter, jsVar, firstToLower, firstToUpper, transformSingleToDouble, removeBlock } from "./util";

var htmlparser = require("htmlparser2");

var defaultSettings = {
  ifEleFlag: false
};

var dslParser = function dslParser(dsl) {
  var _out$data$componentSe;

  defaultSettings.ifEleFlag = false;
  if (!dsl) return {};
  var elements = initParse(dsl);
  if (elements.length <= 0) return {};
  var rootElement = elements.find(function (v) {
    return v.name === 'Document';
  });
  var out = parseJson(rootElement); // 解析到XML里CSS到json，会自动加载到CSS文件及引入渲染

  if ((_out$data$componentSe = out.data.componentSettings) !== null && _out$data$componentSe !== void 0 && _out$data$componentSe.css) {
    out.css = out.data.componentSettings.css;
    delete out.data.componentSettings.css;
  }

  if (defaultSettings.ifEleFlag) {
    out = addIfElementForJson(out);
  }

  return out;
};

export var parseJson = function parseJson(node, parent, child) {
  if (!node) return null;
  var element = null;
  var txt = '';
  var ifEffect = judgeIfEffectNode(node);

  if (ifEffect && _isBoolean(ifEffect)) {
    var type = jsVar(node.name);

    if (parent && parent.type === 'headerCell') {
      element = createRowcellChild(node);
    } else if (!judgeIfEffectType(node, type)) {
      element = parent;
    } else if (child) {
      element = child;
    } else {
      element = createJson();
    }

    if (!element.type) {
      // 定义type类型
      getJsonNameByNode(node, element);
    }

    if (!element.elements) {
      element.elements = [];
    }

    var _node$children = node.children,
        children = _node$children === void 0 ? [] : _node$children,
        _node$attribs = node.attribs,
        attribs = _node$attribs === void 0 ? {} : _node$attribs;

    if (children.length > 0) {
      for (var i = 0; i < children.length; i += 1) {
        var item = children[i];

        if (!(item.type === 'text' && attribs.href && attribs.href.includes(item.data.substring(2, item.data.length - 3)))) {
          var childType = jsVar(item.name);

          if (childType === 'Form.Item') {
            (function () {
              var formAttr = getFormAttr(item.attribs);
              var childJson = createJson({
                data: _objectSpread({}, formAttr)
              });
              item.children.forEach(function (child) {
                parseJson(child, element, childJson);
              });
            })();
          } else {
            parseJson(item, element);
          }
        }
      }
    }

    if (Object.keys(attribs).length > 0) {
      if (type === 'Radio') {
        addOptionsToRadioGroup(attribs, element);
      } else {
        transformNodeAttrs(attribs, element);
      }
    } // }

  }

  if (ifEffect && typeof ifEffect === 'string') {
    txt = ifEffect;
  }

  if (txt) {
    if (element && element.type === 'text') {
      element.data.text = txt;
    } else if (parent && parent.type === 'button') {
      addTextToParent(parent, txt);
    } else if (parent && parent.type === 'headerCell') {
      addRowCellToHeaderCell(parent, txt);
    } else if (parent && parent.type === 'rowCell') {
      addRenderTextToRowCell(parent, txt);
    } else if (element && element.data.componentSettings) {
      element.data.componentSettings.text = txt;
    } else if (!element && parent && defaultTarget.includes(parent.type)) {
      // 动态创建text
      element = createChild(txt);
    }
  }

  if (parent && element && parent.id !== element.id) {
    parent.elements.push(element);
  }

  return element;
};

var addIfElementForJson = function addIfElementForJson(data) {
  var target = {};

  var recurseFun = function recurseFun(element, obj, deep) {
    var targetJson;
    var ifSettings = element.data.ifSettings,
        _element$elements = element.elements,
        elements = _element$elements === void 0 ? [] : _element$elements;
    element.elements = [];

    if (!obj.elements) {
      obj.elements = [];
    }

    if (deep === 0) {
      Object.keys(element).forEach(function (key) {
        obj[key] = element[key];
      });
      targetJson = obj;
    } else if (ifSettings) {
      if (Object.prototype.hasOwnProperty.call(ifSettings, 'condition')) {
        var ifElement = {
          type: 'if',
          data: {
            settings: {},
            componentSettings: _objectSpread(_objectSpread({}, ifSettings), {}, {
              name: 'If'
            })
          },
          elements: []
        };
        delete element.data.ifSettings;
        ifElement.elements.push(element);
        obj.elements.push(ifElement);
        var length = obj.elements.length;
        targetJson = obj.elements[length - 1].elements[0];
      } else {
        delete element.data.ifSettings;
        var parent = obj.elements.find(function (v) {
          return v.type === 'if' && v.elements.length < 2;
        });

        if (parent) {
          parent.elements.push(element);
          var _length = parent.elements.length;
          targetJson = parent.elements[_length - 1];
        }
      }
    } else {
      obj.elements.push(element);
      var _length2 = obj.elements.length;
      targetJson = obj.elements[_length2 - 1];
    }

    elements.forEach(function (item) {
      if (targetJson) {
        recurseFun(item, targetJson);
      }
    });
  };

  recurseFun(cloneDeep(data), target, 0);
  return target;
};

var addRowCellToHeaderCell = function addRowCellToHeaderCell(element, txt) {
  if (!element.elements) {
    element.elements = [];
  }

  var child = createChild(txt, true);
  element.elements.push(child);
};

var createChild = function createChild(txt, createRowCell) {
  var child;

  if (txt.indexOf("{{") > -1 && txt.indexOf("}}") > -1) {
    // expression表达式
    if (createRowCell) {
      child = createTableRowCell({
        expression: removeBlock(txt)
      });
    } else {
      child = createExpression({
        data: {
          componentSettings: {
            expression: removeBlock(txt)
          }
        }
      });
    }
  } else {
    // text普通文本
    child = createText({
      data: {
        text: deleteSpaceAndEnter(txt)
      }
    });
  }

  return child;
};

var addTextToParent = function addTextToParent(element, txt) {
  if (!element.elements) {
    element.elements = [];
  }

  var child = createText({
    data: {
      text: deleteSpaceAndEnter(txt)
    }
  });
  element.elements.push(child);
};

var addRenderTextToRowCell = function addRenderTextToRowCell(element, txt) {
  if (!element.data.componentSettings) {
    element.data.componentSettings = {};
  }

  element.data.componentSettings.renderText = deleteSpaceAndEnter(txt);
};

var createRowcellChild = function createRowcellChild(node) {
  var rowCell = createTableRowCell({
    elements: []
  });
  var name = node.name,
      attribs = node.attribs;
  rowCell.data.componentSettings.renderType = name === 'a' ? firstToLower('link') : firstToLower(name);

  if (attribs.type) {
    rowCell.data.componentSettings.type = attribs.type;
    delete attribs.type;
  }

  return rowCell;
};

var initParse = function initParse(dsl) {
  var elements = [];

  try {
    elements = htmlparser.parseDOM(dsl, {
      lowerCaseTags: false,
      lowerCaseAttributeNames: false
    });
  } catch (e) {
    console.error(e.message, e.stack);
    showError(e.stack);
  }

  return elements;
}; // 判断解析的json元素是否有效，去除空格元素


var judgeIfEffectNode = function judgeIfEffectNode(node) {
  var type = node.type,
      nodeType = node.nodeType,
      data = node.data,
      name = node.name,
      _node$children2 = node.children,
      children = _node$children2 === void 0 ? [] : _node$children2;

  if (name === 'col' && children.length <= 0) {
    return false;
  }

  if ([3, 4].includes(nodeType)) {
    var text = deleteSpaceAndEnter(data);
    return text;
  }

  if (type === 'tag') {
    return true;
  }

  return true;
};

var judgeIfEffectType = function judgeIfEffectType(node, name) {
  if (["Row", "Col"].includes(name)) {
    var _node$attribs2 = node.attribs,
        attribs = _node$attribs2 === void 0 ? {} : _node$attribs2;

    if (attribs.id) {
      return true;
    }

    return false;
  }

  if (name === 'Radio') {
    return false;
  }

  return true;
};

export var getJsonNameByNode = function getJsonNameByNode(node, obj) {
  obj = obj || {};
  var tagName = node.tagName,
      _node$attribs3 = node.attribs,
      attribs = _node$attribs3 === void 0 ? {} : _node$attribs3;

  if (attribs.isBlock) {
    obj.type = 'Document';
    obj.name = tagName;
  } // else if (node.type) {
  //   obj.type = node.type;
  // }
  else {
      obj.type = transformType(tagName);
    }

  return obj;
};
export var transformType = function transformType(name) {
  var tagName = Object.keys(tagNameMaps).find(function (v) {
    return tagNameMaps[v] === name;
  }) || name;
  return firstToLower(jsVar(tagName));
};

var getFormAttr = function getFormAttr() {
  var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var formSettings = {};
  Object.keys(attrs).forEach(function (key) {
    var realKey = jsVar(key);
    var value = transformValue(attrs[key], realKey);
    formSettings[realKey] = value;
  });
  return {
    formSettings: formSettings
  };
};

var createJson = function createJson() {
  var _opts$data;

  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var json = {
    elements: [],
    data: _objectSpread(_objectSpread({}, opts.data || {}), {}, {
      settings: _objectSpread({}, ((_opts$data = opts.data) === null || _opts$data === void 0 ? void 0 : _opts$data.settings) || {})
    })
  };
  return json;
};

var addOptionsToRadioGroup = function addOptionsToRadioGroup(attrs, element) {
  if (!element.data.formItemSettings) {
    element.data.formItemSettings = {};
  }

  if (!element.data.formItemSettings.options) {
    element.data.formItemSettings.options = [];
  }

  element.data.formItemSettings.options.push({
    label: attrs.text,
    value: attrs.value
  });
};

var getEventKey = function getEventKey(key) {
  var eventKey = key;
  eventKey = eventKey.replace('v-on:', '');

  if (eventKey.startsWith('@')) {
    eventKey = eventKey.substr(1);
  }

  return "on".concat(firstToUpper(eventKey));
};

var transformNodeAttrs = function transformNodeAttrs(attrs, element) {
  initAttrForElement(element);
  var attr = element.data;
  Object.keys(attrs).forEach(function (key) {
    var realKey = jsVar(key);
    var value = transformValue(attrs[key], realKey);

    if (['id', 'path'].includes(realKey)) {
      element[realKey] = value;
    } else if (realKey === 'name') {
      initAttrForElement(element, realKey, value);
    } else if (['className', 'class'].includes(realKey)) {
      var _attr$className = attr.className,
          className = _attr$className === void 0 ? '' : _attr$className;

      if (className.length <= 0) {
        className = value;
      } else {
        className += " ".concat(value);
      }

      attr.className = className;
    } else if (["v-bind:dataSource", ":dataSource", "dataSource"].includes(realKey)) {
      var sourceKey = 'dataSourceVariable';
      attr.componentSettings[sourceKey] = value;
    } else if (['visible', 'v-bind:visible', ':visible'].includes(realKey)) {
      // 普通属性
      attr.settings.visible = value;
    } else if (['disabled', 'v-bind:disabled', ':disabled'].includes(realKey)) {
      attr.formItemSettings.disabled = value;
    } else if (['width', 'height'].includes(realKey)) {
      // 普通属性
      if (!attr.settings[realKey]) {
        attr.settings[realKey] = {};
      }

      attr.settings[realKey].value = value;
    } else if (['span', 'offset'].includes(realKey)) {
      // 普通属性
      if (!attr.settings.cols) {
        attr.settings.cols = {};
      }

      attr.settings.cols[realKey] = value;
    } else if (realKey.startsWith('v-on:') || realKey.startsWith('@')) {
      // 事件
      if (!attr.events) {
        attr.events = [];
      }

      var eventFun = value;
      var eventKey = getEventKey(realKey);
      attr.events.push({
        event: eventKey,
        function: {
          value: eventFun,
          relation: _defineProperty({}, eventFun, 'commonPath-action')
        }
      });
    } else if (realKey === 'href') {
      if (element.type !== 'rowCell') {
        // href 要转成 事件类型
        if (!attr.events) {
          attr.events = [];
        }

        if (value.includes('http://') || value.includes('https://')) {
          attr.events.push({
            event: 'onClick',
            function: {
              value: 'url',
              relation: {}
            },
            parameter: {
              URL: value
            }
          });
        } else {
          var _value$split = value.split('/'),
              _value$split2 = _toArray(_value$split),
              _eventFun = _value$split2[0],
              rest = _value$split2.slice(1);

          attr.events.push({
            event: 'onClick',
            function: {
              value: _eventFun,
              relation: _defineProperty({}, _eventFun, 'commonPath-page')
            },
            parameter: _toConsumableArray(rest)
          });
        }
      } else {
        attr.componentSettings.to = value;
      }
    } else if (realKey === 'isBlock') {
      // blockSettings区块属性
      if (!attr.blockSettings) {
        attr.blockSettings = {};
      }

      attr.blockSettings[realKey] = value;
    } else if (['v-if', 'v-else', 'currentCondition'].includes(realKey)) {
      // 条件选择器属性
      if (!attr.ifSettings) {
        attr.ifSettings = {};
      }

      if (realKey === 'v-if') {
        attr.ifSettings.condition = value;
      } else if (realKey === 'currentCondition') {
        attr.ifSettings.currentCondition = value;

        if (!defaultSettings.ifEleFlag) {
          // 判断当前元素是否为if表达式子元素
          defaultSettings.ifEleFlag = true;
        }
      }
    } else {
      if (attr.formSettings && element.type === 'form') {
        attr.formSettings[realKey] = value;
      } else if (attr.formItemSettings) {
        attr.formItemSettings[realKey] = value;
      } else {
        attr.componentSettings[realKey] = value;
      }
    }
  });
}; // 根据element类型创建属性key


var initAttrForElement = function initAttrForElement(element, key, value) {
  if (!element.data) {
    element.data = {};
  }

  if (!element.data.settings) {
    element.data.settings = {};
  }

  if (defaultTarget.includes(element.type)) {
    if (element.type === 'form') {
      addAttr('formSettings', element.data, key, value);
    } else {
      addAttr('componentSettings', element.data, key, value);
    }
  } else if (formPlugins.includes(element.type)) {
    addAttr('formItemSettings', element.data, key, value);
  } else {
    addAttr('componentSettings', element.data, key, value);
  }
};

var addAttr = function addAttr(targetKey, target, key, value) {
  if (!target[targetKey]) {
    target[targetKey] = {};
  }

  if (key && value) {
    target[targetKey][key] = value;
  }
};

var transformValue = function transformValue(str, key) {
  var value = str;

  if (typeof str === 'string') {
    value = transformSingleToDouble(str); // 字符串转对象

    if (value.indexOf("{{") > -1 && value.indexOf("}}") > -1) {
      value = removeBlock(value);
    } // 字符串转数组


    if (value.startsWith("{") && endWidth("}", value) || value.startsWith("[") && endWidth("]", value)) {
      value = value.replace(/(.*),}/, '$1}');
      value = JSON.parse(value);
    } // 字符串转数字


    if (/^\d+$/.test(value) && !['checkedKey', 'unCheckedKey'].includes(key)) {
      value = parseInt(value);
    } // 字符串转Boolean


    if (value === 'false' && !['checkedKey', 'unCheckedKey'].includes(key)) {
      value = false;
    }

    if (value === 'true' && !['checkedKey', 'unCheckedKey'].includes(key)) {
      value = true;
    }

    return value;
  }
};

export default dslParser;
//# sourceMappingURL=dslParser.js.map