/**
 * @since Last modified: 2024-01-18 16:17:08
 * @namespace dom
 * @description Common operation collection of nodes.Include get,create & json.
 * @see {@link https://codepen.io/axui/pen/mdvwQYo|demo @ codepen}
 */
'use strict';
import getDataType from './getDataType';
import requireTypes from './requireTypes';
const dom: any = {
    /**
 * @memberOf dom
 * @description Get a HTMLElement node.Support to get a real node or virtual node 
 * @param {string|HTMLElement} obj  - It can be node  or node selector such as#ID, .classname, NODENAME, [attribute]
 * @param {HTMLElement} parent  - Parent node, get sub-node from this node, default document.body
 * @returns {HTMLElement|null} Return a node or null
 * @see {@link https://codepen.io/axui/pen/JjxNQEO|demo @ codepen}
 * @example
 * ax.dom.get('#demo');
 * <!--return a HTMLElement node-->
 */
    get: function (obj: any, parent: any = document.body): any {
        let type = getDataType(obj), result = null;
        if (obj) {
            if (type.includes('HTML')) {
                result = obj;
            } else if (type === 'String') {
                try {
                    result = parent.querySelector(obj.trim());
                } catch {
                    result = null;
                }
            }
        }
        return result;
    },
    /**
 * @memberOf dom
 * @description Create a node or a group of father -son nodes. 
 * @param {string} name  - Node name, requierd.
 * @param {object} [attrs]  - Node attributes.Format : {class:'demo',style:'width:100px;height:50px;',disabled:''}
 * @param {string|number|array} [content]  - Node content.If it is an array,create a sub-node of the cycle.
 * @returns {HTMLElement|null} Return a node or null
 * @see {@link https://codepen.io/axui/pen/LYqzJyd|demo @ codepen}
 * @example
 * ax.dom.create('div',{class:'demo'},'I love you');
 * <!--return a HTMLElement node-->
 */
    create: function (name: string, attrs?: T_obj, content?: string): any {
        if (!name) {
            return null;
        }
        let rootName = name.toLowerCase().trim(),
            rootDom = document.createElement(rootName),
            attrsType = getDataType(attrs),
            loop = (dom: any, data: any) => {
                if (data === '' || data === null || data === undefined) {
                    return false;
                }
                let dataType = getDataType(data);
                if (rootName === 'template') {
                    dom.innerHTML = data;
                } else {
                    if (dataType === 'Array' && data.length > 0) {
                        data.forEach((i: T_obj) => loop(dom, i));
                    } else if (dataType.includes('HTML')) {
                        dom.appendChild(data);
                    } else {
                        dom.insertAdjacentHTML('beforeEnd', data);
                    }
                }
            }
        if (attrs && attrsType === 'Object') {
            for (let k in attrs) {
                attrs.hasOwnProperty(k) ? rootDom.setAttribute(k, attrs[k]) : null;
            }
        }
        loop(rootDom, content);
        return rootDom;
    },
    /**
 * @since Last modified: 2023-11-14 16:49:23
 * @function attrToJson
 * @description Convert the attribute text on the node to JSON.
 * @param {getEl} elem  - Target node or node selector, please refer to the util : getEl.
 * @param {string} attr  - Node attribute.
 * @returns {Object|{}} - Return a json.
 * @see {@link https://codepen.io/axui/pen/rNPmEqz|demo @ codepen}
 * @example
 * <div ax="a:0,b:1"></div>
 * ax.dom.json('#demo', 'ax');
 * <!--return {a:0,b:1}-->
 */
    json: function (elem: any, attr: string): T_obj {
        requireTypes(attr, 'string');
        let dom = this.get(elem),
            domAttr = dom.getAttribute(attr),
            result = {};
        if (dom && attr && domAttr && domAttr.includes(':')) {
            let text = domAttr.trim();
            !text.startsWith('{') ? text = `{${text}}` : null;
            result = new Function('return ' + text)();
        }
        return result;
    }
}
export default dom;
