const ui = (() => {

    /**
     * @template {HTMLElement} T
     * @param {T} element 
     * @param {Object<string, any>} props 
     * @param  {...string|HTMLElement} children 
     * @returns {T}
     */
    function base(element, props, ...children) {
        if (props !== undefined) {
            if (props instanceof HTMLElement || typeof props === "string") {
                element.append(props)
            } else {
                for (const [key, value] of Object.entries(props)) {
                    element[key] = value
                }
            }
            element.append(...children)
        }
        return element
    }

    
    /**
     * 
     * @param {keyof HTMLElementTagNameMap} elementName 
     * @param {Object<string, any>} props 
     * @param  {...string|HTMLElement} children 
     * @returns 
     */
    function tag(elementName, props, ...children) {
        return base(document.createElement(elementName), props, ...children)
    }

    /**
     * This callback is called anytime the publisher `publish` method is called.
     * @template T
     * @callback subscriberCallback
     * @param {T} element
     * @param {*} eventData
     * @param {replaceElementInMemoryAndInDomWith<HTMLElement>} eventData
     * @returns {void}
    */

    /**
     * This callback is called when we want to replace the subscribers original 
     * element with a new element
     * @template T
     * @callback replaceElementInMemoryAndInDomWith
     * @param {T} element
     * @returns {void}
    */



    function ready(fn) {
        //console.log("ready it");
        if (document.readyState !== 'loading') {
            fn();
        } else {
            document.addEventListener('DOMContentLoaded', fn);
        }
    }

    /**
     * 
     * @param {subscriberCallback<HTMLElement>} fn 
     * @param  {HTMLElement} element 
     */
    function clickable(fn, element) {
        element.onclick = () => fn(element)
        return element
    }

    function publisher() {
        const eventName = uuidv4()
        return {
            publish(data) {
                document.dispatchEvent(new CustomEvent(eventName, {
                    detail: data,
                }))
            },

            /**
             * @template {HTMLElement} T
             * @param {T} element 
             * @param {subscriberCallback<T>} fnElementEventData 
             */
            makeSubscriber(element, fnElementEventData) {
                document.addEventListener(eventName, (e) => {
                    fnElementEventData(element, e.detail, (newElement) => {
                        element.replaceWith(newElement)
                        element = newElement
                    })
                })
                return element
            }
        }
    }

    function uuidv4() {
        return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        );
    }

    /**
     * gets the first item the matches the query and then gives its children as declared 
     * in the buildFn
     * @param {string} query 
     * @param {function} buildFn 
     */
    function root(query, buildFn) {
        const node = document.querySelector(query)
        buildFn(node)
    }

    return {
        ready,
        clickable,
        publisher,
        tag,
    }
})()