/**
 * @since Last modified: 2024-08-13 20:18:04
 * @function init
 * @description Perform initialization on nodes using ax-* attribute.
 * @param {string} type  - initialization type.The formats are:`type='Dialog',type=['Dialog','Accordion'...],type=null`
 * @param {getEl} parent  - Specify the child nodes under the parent node to perform initialization.
 * @returns {Object} - Return ax.
 * @see {@link https://codepen.io/axui/pen/BabKdJZ|demo @ codepen}
 * @example
 * ax.init();
 * <!--return {length:30}-->
 */
'use strict';
import ax from "../ax";
import Lazy from "../modules/Lazy";
import elProps from "./elProps";
import getDataType from "./getDataType";
import getEl from "./getEl";
import getEls from "./getEls";
import isEmpty from "./isEmpty";
import strToJson from "./strToJson";
const init = (type, parent) => {
    let parentEl = getEl(parent) || document.body, evalFn = new Function('el', 'module', `try {return new module(el)} catch {return null}`), moduleNodeList = [], setProp = (node, module) => {
        elProps(node)?.add(module);
    }, getUsableModules = () => {
        let result = [];
        for (let [key, value] of Object.entries(ax)) {
            value.hostType === 'el' ? result.push(key) : null;
        }
        return result;
    }, getNodeList = (types) => {
        let allModules = getUsableModules(), modules = !isEmpty(types) ? types.filter(k => allModules.includes(k)) : allModules, modulesNodes = modules.map(k => {
            return { module: k, nodeList: [...parentEl.querySelectorAll(`[ax-${k}]`)].filter((i) => !i.ax || (i.ax && !i.ax[k])) };
        });
        return modulesNodes;
    }, activeFun = (nodes) => {
        for (let v of nodes) {
            if (v.nodeList.length === 0) {
                continue;
            }
            if (['Dialog', 'Drawer', 'Popup'].includes(v.module)) {
                higherParent(v.module, v.nodeList);
            }
            else {
                v.nodeList.forEach((k) => {
                    let ins = evalFn(k, ax[v.module]);
                    ins ? setProp(k, v.module) : null;
                });
            }
        }
    }, higherParent = (module, nodes) => {
        let eachInstance = (arr, parent) => {
            arr.forEach((k) => {
                let ins = evalFn(k, ax[module]), children;
                if (ins) {
                    k[module] = true;
                    parent ? ins.targetEl.style.zIndex = parseInt(getComputedStyle(parent.targetEl).zIndex) + 1 : null;
                    children = [...ins.contEl.querySelectorAll(`[ax-${module}]`)];
                    children.length > 0 ? eachInstance(children, ins) : null;
                }
            });
        };
        eachInstance(nodes);
    };
    if (!isEmpty(type)) {
        let moduleType = getDataType(type), types;
        types = (moduleType === 'String') ? [type] :
            (moduleType === 'Array') ? type : [];
        moduleNodeList = types.length > 0 ? getNodeList(types) : [];
    }
    else {
        moduleNodeList = getNodeList();
    }
    moduleNodeList.length > 0 ? activeFun(moduleNodeList) : null;
    let lazySrcs = getEls('[lazy-src]', parentEl), lazyAsyncs = getEls('[lazy-async]', parentEl);
    for (let k of lazySrcs) {
        if (k?.ax?.lazy)
            continue;
        new Lazy(k, {
            content: k.getAttribute('lazy-src'),
            type: 'src'
        });
    }
    for (let k of lazyAsyncs) {
        if (k?.ax?.lazy)
            continue;
        new Lazy(k, {
            content: k.getAttribute('lazy-async'),
            contType: k.getAttribute('lazy-type'),
            contData: strToJson(k.getAttribute('lazy-data')),
            tplStr: k.getAttribute('lazy-tpl'),
            type: 'async'
        });
    }
    return ax;
};
export default init;
