Complianz integration for async google maps in FacetWP 4.4.0+

<?php 

/**
 * prevent default map loading 
 **/
add_filter( 'facetwp_load_gmaps', '__return_false' ); 

/**
 * load gmaps script for cmplz
 */
add_filter( 'cmplz_added_scripts', function( $added_scripts ) {
    $params = [
        'key'   => FWP()->display->get_gmaps_api_key(),
        'v'     => 'quarterly',
    ];
    $params_string = '';
    foreach ( apply_filters( 'facetwp_gmaps_params', $params ) AS $param => $val ) {
        $params_string .=  $param . ': "' . $val . '",';
    }

    $script = '(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. FacetWP\'s instance is ignored."):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({';
    $script .= $params_string;
    $script .= '});';

    $added_scripts[] = [
        'name' => 'FacetWP',
        'category' => 'marketing',
        'editor' => $script,
        'async' => 0
    ];

    return $added_scripts;

});

/**
 * Init map after cookies accepted
 *
 */

add_action('wp_enqueue_scripts', function()
{
    ob_start();
?>
    <script>
        /**
         * Make functions await for 'ms' milliseconds
         * https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
         *
         */
        function sleep(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        /**
         * Wait for 'facetwp-map' to be initialized
         *
         */
        const checkIfMapIsInitialized = () => {
            const map = document.getElementById('facetwp-map');
            return map.children.length > 0 && FWP_MAP.markersArray.length > 0;
        }

        /**
         * Wait for 'FWP', 'FWP_MAP' and 'FWP_MAP.map' to be set
         *
         */
        const checkIfFWPExists = async () => {
            if (typeof FWP !== 'undefined' && typeof FWP_MAP !== 'undefined' && typeof FWP_MAP.map !== 'undefined') {
                return true;
            }
            await sleep(500);
            checkIfFWPExists();
        }

        /**
         * Reinitialize FacetWP Google Maps' map
         *
         */
        const reinitializeMap = async () => {
            FWP.loaded = false;
            delete FWP.frozen_facets.map; // change 'map' to name of your map
            FWP.refresh();
            await sleep(6000);
            if (checkIfMapIsInitialized() !== true) {
                reinitializeMap();
            }
        }

        const fixMap = async (event) => {
            if (!cmplz_has_consent("marketing")) {
                return;
            }
            if (event.type === "cmplz_enable_category") {
                document.removeEventListener('cmplz_enable_category', fixMap);
                window.removeEventListener('load', fixMap);
            }
            await checkIfFWPExists();

            if (checkIfMapIsInitialized() !== true) {
                await reinitializeMap();
            }
        }

        document.addEventListener('cmplz_enable_category', fixMap);
        window.addEventListener('load', fixMap);
    </script>
<?php
    $script = ob_get_clean();
    $script = str_replace(array('<script>', '</script>'), '', $script);
    wp_add_inline_script('cmplz-cookiebanner', $script);

}, PHP_INT_MAX);