"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.xmlToJson = void 0;
/* eslint-disable */
const util_1 = require("./util");
const cloneDeep_1 = require("lodash/cloneDeep");
const { DOMParser } = require('xmldom');
const defaultSettings = {
    ifEleFlag: false
};
const handleJsonName = (node, obj) => {
    var _a;
    obj = obj || {};
    const nodeName = node.localName || node.tagName;
    if ((_a = node.attributes) === null || _a === void 0 ? void 0 : _a.isBlock) {
        obj.type = 'Document';
        obj.name = nodeName;
    }
    else if (node.type) {
        obj.type = node.type;
    }
    else {
        obj.type = transFormType(nodeName);
    }
    return obj;
};
const xmlToJson = function (xml, extended = false) {
    var _a;
    if (!xml)
        return {};
    defaultSettings.ifEleFlag = false;
    function parseXML(node, simple = false) {
        if (!node)
            return null;
        let txt = '', obj = null, att = null;
        const { childNodes } = node;
        if (childNodes) {
            obj = handleJsonName(node, obj);
            if (childNodes.length > 0) {
                for (let i = 0; i < childNodes.length; i += 1) {
                    const cn = childNodes.item(i);
                    const cnn = jsVar(cn.localName || cn.tagName);
                    if (['Row', 'Col'].includes(cnn)) {
                        const childNodesInner = filterEffectChildNode(cn);
                        if (!obj.elements) {
                            obj.elements = [];
                        }
                        childNodesInner.forEach((child) => {
                            obj.elements.push(parseXML(child));
                        });
                        continue;
                    }
                    if (cnn === 'Form.Item') {
                        const childNodesInner = filterEffectFromItemChildNode(cn);
                        if (!obj.elements) {
                            obj.elements = [];
                        }
                        childNodesInner.forEach((child) => {
                            obj.elements.push(parseXML(child));
                        });
                        continue;
                    }
                    if (!cn.tagName) {
                        const cnv = cn.textContent;
                        if (!(cnv.match(/^\s+$/))) {
                            txt += cnv.replace(/^\s+/, '').replace(/\s+$/, '');
                        }
                        continue;
                    }
                    else {
                        obj = obj || {};
                        if (obj.type === 'headerCell') {
                            cn.type = 'rowCell'; // 标记rowCell
                        }
                        if (obj.elements) {
                            if (!obj.elements.length)
                                obj.elements = myArr(obj.elements);
                            obj.elements = myArr(obj.elements);
                            obj.elements[obj.elements.length] = parseXML(cn, true);
                            obj.elements.length = obj.elements.length;
                        }
                        else {
                            obj.elements = [parseXML(cn)];
                        }
                    }
                }
            }
        }
        if (node.attributes) {
            if (node.attributes.length > 0) {
                att = {};
                obj = obj || {};
                if (obj.type === 'rowCell') {
                    // 表格bodyCell transform和普通组件区分开
                    transformRowCellAttrs(node.attributes, obj, att, transFormType(node.localName || node.tagName), node.textContent);
                }
                else {
                    transformNodeAttrs(node.attributes, obj, att, null);
                }
            }
        }
        if (node.formSettings && node.formSettings.length > 0) {
            transformNodeAttrs(node.formSettings, obj, att, "formSettings");
        }
        if (!obj.elements) {
            obj.elements = [];
        }
        if (!obj.data) {
            obj.data = {};
        }
        if (obj) {
            txt = (obj.text) ? ([obj.text || '']).concat([txt]) : txt;
            if (txt) {
                if (obj.type === 'text') {
                    obj.data.text = (0, util_1.createValue)(txt);
                }
                else if (obj.data.formItemSettings) {
                    obj.data.formItemSettings.text = txt;
                }
            }
            txt = '';
        }
        let out = obj || txt;
        if (extended) {
            if (txt)
                out = {};
            txt = out.text || txt || '';
            if (txt)
                out.text = txt;
            if (!simple)
                out = myArr(out);
        }
        return out;
    }
    if (typeof xml === 'string')
        xml = text2xml(xml);
    if (!xml)
        return;
    if (!xml.nodeType)
        return;
    if (xml.nodeType === 3 || xml.nodeType === 4)
        return xml.nodeValue;
    let root = (xml.nodeType === 9) ? xml.documentElement : xml;
    let out = parseXML(root, true);
    xml = null;
    root = null;
    // 解析到XML里CSS到json，会自动加载到CSS文件及引入渲染
    if ((_a = out.data.formItemSettings) === null || _a === void 0 ? void 0 : _a.css) {
        out.css = out.data.formItemSettings.css;
        delete out.data.formItemSettings.css;
    }
    if (defaultSettings.ifEleFlag) {
        out = addIfElementForJson(out);
    }
    return out;
};
exports.xmlToJson = xmlToJson;
const addIfElementForJson = (data) => {
    let target = {};
    const recurseFun = (element, obj, deep) => {
        let targetJson;
        const { data: { ifSettings }, elements = [] } = element;
        element.elements = [];
        if (!obj.elements) {
            obj.elements = [];
        }
        if (deep === 0) {
            Object.keys(element).forEach(key => {
                obj[key] = element[key];
            });
            targetJson = obj;
        }
        else if (ifSettings) {
            if (Object.prototype.hasOwnProperty.call(ifSettings, 'condition')) {
                const ifElement = {
                    type: 'if',
                    data: {
                        settings: {},
                        componentSettings: Object.assign(Object.assign({}, ifSettings), { name: 'If' })
                    },
                    elements: []
                };
                delete element.data.ifSettings;
                ifElement.elements.push(element);
                obj.elements.push(ifElement);
                const length = obj.elements.length;
                targetJson = obj.elements[length - 1].elements[0];
            }
            else {
                delete element.data.ifSettings;
                const parent = obj.elements.find(v => v.type === 'if' && v.elements.length < 2);
                if (parent) {
                    parent.elements.push(element);
                    const length = parent.elements.length;
                    targetJson = parent.elements[length - 1];
                }
            }
        }
        else {
            obj.elements.push(element);
            const length = obj.elements.length;
            targetJson = obj.elements[length - 1];
        }
        elements.forEach((item) => {
            if (targetJson) {
                recurseFun(item, targetJson);
            }
        });
    };
    recurseFun((0, cloneDeep_1.default)(data), target, 0);
    return target;
};
const handleAttr = (value, atn, att, obj) => {
    let atv = transformSingleToDouble(value);
    // 字符串转对象
    if (atv.indexOf("{{") > -1 && atv.indexOf("}}") > -1) {
        if (atn === 'dataSource' && ['table', 'table-edit'].includes(obj.type)) {
            att.tableSettings['dataSourceVariable'] = removeBlock(atv) === '[]' ? '' : removeBlock(atv);
            atv = '';
        }
        else {
            atv = removeBlock(atv);
        }
    }
    // 字符串转数组
    if ((atv.startsWith("{") && (0, util_1.endWidth)("}", atv)) || (atv.startsWith("[") && (0, util_1.endWidth)("]", atv))) {
        atv = atv.replace(/(.*),}/, '$1}');
        atv = JSON.parse(atv);
    }
    // 字符串转数字
    if (/^\d+$/.test(atv)) {
        atv = parseInt(atv);
    }
    // 字符串转Boolean
    if (atv === 'false') {
        atv = false;
    }
    if (atv === 'true') {
        atv = true;
    }
    return atv;
};
const addName = (attr, key, value) => {
    if (!attr[key]) {
        attr[key] = {};
    }
    attr[key].name = value;
};
const addNameForElement = (value, attr, element) => {
    if (util_1.defaultTarget.includes(element.type)) {
        if (element.type === 'form') {
            addName(attr, 'formSettings', value);
        }
        else {
            addName(attr, 'componentSettings', value);
        }
    }
    else if ((element.type.indexOf('table') || element.type.indexOf('table-edit')) > -1) {
        addName(attr, 'tableSettings', value);
    }
    else if (element.type === 'headerCell') {
        addName(attr, 'columnSettings', value);
    }
    else if (util_1.formPlugins.includes(element.type)) {
        addName(attr, 'formItemSettings', value);
        delete attr.componentSettings;
    }
    else if (attr.formSettings) {
        addName(attr, 'formSettings', value);
    }
    else {
        addName(attr, 'componentSettings', value);
        delete attr.formItemSettings;
    }
};
// headerCell内部节点反序列化
const transformRowCellAttrs = (attributes, obj, att, renderType, renderText) => {
    if (!att.componentSettings) {
        att.componentSettings = {};
    }
    att.componentSettings.renderType = renderType || 'text';
    if (renderText) {
        att.componentSettings.renderText = trim(renderText);
    }
    for (let i = 0; i < attributes.length; i += 1) {
        const at = attributes.item(i);
        const atn = jsVar(at.name);
        const atv = handleAttr(at.value, atn, att, obj);
        if (['id', 'path'].includes(atn)) {
            obj[atn] = atv;
        }
        else if (atn.startsWith('on')) {
            // 事件类型
            if (!att.events) {
                att.events = [];
            }
            const eventFun = atv.startsWith('this.') ? atv.split('this.')[1] : atv;
            att.events.push({ event: atn, function: eventFun });
        }
        else {
            att.componentSettings[atn] = atv;
        }
    }
    if (obj.data) {
        obj.data = Object.assign(obj.data, att);
    }
    else if (Object.keys(att).length > 0) {
        obj.data = att;
    }
};
// 普通节点反序列化
const transformNodeAttrs = (attributes, obj, att, type) => {
    var _a, _b;
    if (!att.settings) {
        att.settings = {};
    }
    for (let i = 0; i < attributes.length; i += 1) {
        const at = attributes.item(i);
        const atn = jsVar(at.name);
        const atv = handleAttr(at.value, atn, att, obj);
        if (['id', 'path', 'for', 'type'].includes(atn)) {
            if (atn === 'type') {
                if (['button', 'input'].includes(obj.type)) {
                    if (!att.formItemSettings) {
                        att.formItemSettings = {};
                    }
                    att.formItemSettings[atn] = atv;
                }
                else {
                    obj[atn] = atv;
                }
            }
            else {
                obj[atn] = atv;
            }
        }
        else if (['className', 'class'].includes(atn)) {
            let { className = '' } = att;
            if (className.length <= 0) {
                className = atv;
            }
            else {
                className += ` ${atv}`;
            }
            att.className = className;
        }
        else if (atn === 'visible') {
            // 普通属性
            att.settings[atn] = atv;
        }
        else if (['width', 'height'].includes(atn)) {
            // 普通属性
            if (!att.settings[atn]) {
                att.settings[atn] = {};
            }
            att.settings[atn].value = atv;
        }
        else if (['span', 'offset'].includes(atn)) {
            // 普通属性
            if (!att.settings.cols) {
                att.settings.cols = {};
            }
            att.settings.cols[atn] = atv;
        }
        else if (atn.startsWith('on')) {
            // 事件类型
            if (!att.events) {
                att.events = [];
            }
            const eventFun = atv.startsWith('this.') ? atv.split('this.')[1] : atv;
            att.events.push({ event: atn, function: eventFun });
        }
        else if (atn === 'isBlock') {
            // blockSettings区块属性
            if (!att.blockSettings) {
                att.blockSettings = {};
            }
            att.blockSettings[atn] = atv;
        }
        else if (['c-if', 'c-else', 'currentCondition'].includes(atn)) {
            // 条件选择器属性
            if (!att.ifSettings) {
                att.ifSettings = {};
            }
            if (atn === 'c-if') {
                att.ifSettings.condition = atv;
            }
            else if (atn === 'currentCondition') {
                att.ifSettings.currentCondition = atv;
                if (!defaultSettings.ifEleFlag) {
                    // 判断当前元素是否为if表达式子元素
                    defaultSettings.ifEleFlag = true;
                }
            }
        }
        else if (obj.type === 'form' || type || (atn === 'name' && obj.type === 'button')) {
            if (!att.formSettings) {
                att.formSettings = {};
            }
            att.formSettings[atn] = atv;
        }
        else if (['table', 'tableEdit'].includes(obj.type)) {
            if (!att.tableSettings) {
                att.tableSettings = {};
            }
            att.tableSettings[atn] = atv;
        }
        else if (obj.type === 'headerCell') {
            if (!att.columnSettings) {
                att.columnSettings = {};
            }
            att.columnSettings[atn] = atv;
        }
        else if (atn === 'componentSettings') {
            att.componentSettings = atv;
        }
        else if (atn === 'name') {
            addNameForElement(atv, att, obj);
        }
        else {
            if (att.componentSettings) {
                att.componentSettings[atn] = atv;
            }
            else {
                if (!att.formItemSettings) {
                    att.formItemSettings = {};
                }
                att.formItemSettings[atn] = atv;
            }
        }
    }
    if (obj.type === 'picker') {
        // 特殊处理picker
        const { elements = [] } = obj;
        if (elements.length === 1) {
            att.formItemSettings.placeholder = (_b = (_a = elements[0].data) === null || _a === void 0 ? void 0 : _a.formItemSettings) === null || _b === void 0 ? void 0 : _b.text;
            obj.elements = [];
        }
    }
    if (obj.type === 'radioGroup') {
        // 特殊处理radioGroup
        const { elements = [] } = obj;
        if (elements.length > 0) {
            const options = [];
            elements.forEach(v => {
                var _a;
                const { text, value } = (_a = v.data) === null || _a === void 0 ? void 0 : _a.formItemSettings;
                options.push({
                    label: text,
                    value
                });
            });
            att.formItemSettings.options = options;
            obj.elements = [];
        }
    }
    if (obj.data) {
        obj.data = Object.assign(obj.data, att);
    }
    else if (Object.keys(att).length > 0) {
        obj.data = att;
    }
};
const trim = (str) => {
    return str.replace(/^\s+/, "").replace(/\s+$/, "");
};
// 转换type字段
const transFormType = (name) => {
    const tagName = Object.keys(util_1.tagNameMaps).find(v => util_1.tagNameMaps[v] === name) || name;
    return firstToLower(jsVar(tagName));
};
const filterEffectChildNode = (parentNode) => {
    const childs = [];
    const recurseFun = (parent) => {
        const { childNodes } = parent;
        if (childNodes && childNodes.length > 0) {
            for (let i = 0; i < childNodes.length; i += 1) {
                const cn = childNodes.item(i);
                if (cn.tagName) {
                    const cnn = jsVar(cn.localName || cn.tagName);
                    if (['Row', 'Col'].includes(cnn)) {
                        recurseFun(cn);
                    }
                    else if (cnn === 'Form.Item') {
                        childs.push(...filterEffectFromItemChildNode(cn));
                    }
                    else {
                        childs.push(cn);
                    }
                }
            }
        }
    };
    recurseFun(parentNode);
    return childs;
};
// 筛选FormItem内的有效组件元素
const filterEffectFromItemChildNode = (formItemNode) => {
    const childs = [];
    const { childNodes } = formItemNode;
    if (childNodes && childNodes.length > 0) {
        for (let i = 0; i < childNodes.length; i += 1) {
            const cn = childNodes.item(i);
            if (cn.tagName) {
                cn.formSettings = formItemNode.attributes;
                childs.push(cn);
            }
        }
    }
    return childs;
};
const jsVar = function (s) {
    if (['c-if', 'c-else'].includes(s)) {
        return String(s || '');
    }
    return String(s || '').replace(/-/g, "_");
};
const firstToLower = (str) => {
    return str.replace(/( |^)[A-Z]/g, (L) => L.toLowerCase());
};
const myArr = function (o) {
    if (!Array.isArray(o))
        o = [o];
    o.length = o.length;
    return o;
};
const text2xml = function (str) {
    return parseXMLOut(str);
};
const parseXMLOut = function (data) {
    let xml = data;
    if (!data || typeof data !== "string") {
        return null;
    }
    xml = xml.replace(/c-else/g, 'c-else="c-else"');
    try {
        xml = new DOMParser().parseFromString(xml, "text/xml");
    }
    catch (e) {
        console.error(e.message, e.stack);
        xml = undefined;
    }
    return xml;
};
// 去除收尾双花括号
const removeBlock = (str) => {
    if (str) {
        const reg = /^\{{/gi;
        const reg2 = /\}}$/gi;
        str = str.replace(reg, '');
        str = str.replace(reg2, '');
        return str;
    }
    return str;
};
// 将字符串单引号替换为双引号
const transformSingleToDouble = (str) => {
    return str.replace(/\'/g, '"');
};
