import type { findBlockedNodes } from "@devowl-wp/headless-content-unblocker";
import { HTML_ATTRIBUTE_VISUAL_PARENT } from "@devowl-wp/headless-content-unblocker";
import { parents, yieldMainThread } from "@devowl-wp/react-utils";

import { MEMORIZE_ELEMENTOR_HANDLER_PROPERTY } from "./hijackElementorOnInit.js";

/**
 * A content got unblocked, let's run custom triggers on them, for example
 * the Elementor ready hook.
 */
function customUnblockTriggers(nodes: ReturnType<typeof findBlockedNodes>) {
    const {
        elementorFrontend,
        TCB_Front,
        jQuery,
        showGoogleMap,
        et_pb_init_modules,
        et_calculate_fullscreen_section_size,
        tdYoutubePlayers,
        tdVimeoPlayers,
        FWP,
        avadaLightBoxInitializeLightbox,
        WPO_LazyLoad,
        mapsMarkerPro,
        theme,
        em_maps_load,
        fluidvids,
        bricksLazyLoad,
        BuddyBossTheme,
    } = window as any;

    let foundWpgb = false;

    // https://www.mapsmarker.com/
    if (mapsMarkerPro) {
        Object.keys(mapsMarkerPro).forEach((k) => mapsMarkerPro[k].main());
    }

    // https://ovatheme.com/
    theme?.initGoogleMap?.();

    // https://wordpress.org/plugins/events-manager/
    em_maps_load?.();

    const runElementorReadyTrigger: HTMLElement[] = [];

    for (const { node } of nodes) {
        const { className, id } = node;

        // Elementor https://git.io/JsXoh
        if (!node.hasAttribute(MEMORIZE_ELEMENTOR_HANDLER_PROPERTY)) {
            runElementorReadyTrigger.push(node);

            if (node.getAttribute(HTML_ATTRIBUTE_VISUAL_PARENT) === ".elementor-widget-container") {
                runElementorReadyTrigger.push(...parents(node, ".elementor-widget", 1));
            }
        }

        // WP Grid Builder
        if (id.startsWith("wpgb-") || className.startsWith("wpgb-")) {
            foundWpgb = true;
        }

        if (jQuery) {
            const $node = jQuery(node);

            // Thrive Visual Editor
            if (TCB_Front && jQuery && className.indexOf("tcb-yt-bg") > -1) {
                if ($node.is(":visible")) {
                    TCB_Front.playBackgroundYoutube($node);
                }
            }

            // Goodlayer page builder
            jQuery(document.body).gdlr_core_content_script?.($node);
        }
    }

    // Thrive Architect
    TCB_Front?.handleIframes(TCB_Front.$body, true);

    // https://avada.theme-fusion.com/design-elements/lightbox-element/
    avadaLightBoxInitializeLightbox?.();

    // FacetWP
    if (FWP) {
        FWP.loaded = false;
        FWP.is_bfcache = false;
        FWP.paged = FWP.settings?.pager?.page || 1;
        FWP.refresh();
    }

    // WP Optimize lazyloading
    WPO_LazyLoad?.update();

    // Bricks Builder lazyloading
    bricksLazyLoad?.();

    // https://qodeinteractive.com/wordpress-theme/bridge-creative-multi-purpose-wordpress-theme/
    showGoogleMap?.();

    // BuddyBoss Theme videos
    BuddyBossTheme?.bbFitVideo();

    // jQuery plugins
    if (jQuery) {
        // https://github.com/ressio/lazy-load-xt
        jQuery(window).lazyLoadXT?.();

        // https://www.checkoutwc.com/documentation/how-to-enable-address-autocomplete/
        jQuery(document.body).trigger("cfw_load_google_autocomplete");

        // Enfold video embeds
        jQuery(".av-lazyload-immediate .av-click-to-play-overlay").trigger("click");
    }

    // Divi modules (e.g. Contact Forms and Newsletter signups)
    if (et_pb_init_modules) {
        // We need to reset the resize event listener as it results in an "resize" loop:
        // https://wordpress.org/support/topic/ultimatemember-profile-picture-upload-flickering/page/2/#post-15471580
        jQuery(window).off("resize", et_calculate_fullscreen_section_size);
        et_pb_init_modules();
    }

    // tagDiv Composer
    tdYoutubePlayers?.init();
    tdVimeoPlayers?.init();

    // WP Grid Builder (the custom event triggers an AJAX request, so do this only if we unblock a WPGB element)
    try {
        foundWpgb && window.dispatchEvent(new CustomEvent("wpgb.loaded"));
    } catch (e) {
        // Silence is golden.
    }

    // fluidvids compatibility
    fluidvids && fluidvids.render();

    // wait for all hook initializers for the ready callback
    yieldMainThread().then(() => {
        if (elementorFrontend) {
            for (const node of runElementorReadyTrigger) {
                elementorFrontend.elementsHandler.runReadyTrigger(node);
            }
        }
    });
}

export { customUnblockTriggers };
