Re-initialize Ays Pro Chartify charts after a FacetWP refresh

<?php
// Re-initialize Ays Pro Chartify charts used in a listing template, after a FacetWP refresh
// https://wordpress.org/plugins/chart-builder/
// https://ays-pro.com/wordpress/chart-builder
// Note: this only works in WP archive or custom WP_Query based templates, NOT in FacetWP Listing Builder listings. There is no solution for those.
// This solution works for both JS and Google charts

add_action('facetwp_scripts', function() {
  ?>
  <script>
    (function($) {
      if (typeof FWP !== 'undefined') {

        // Note: this only works in WP archive or custom WP_Query templates, NOT in FacetWP Listing Builder listings,
        // because in those, the respons is not the whole body (only the listing content) and thus it has no access to
        // the updated #chart-builder-chart-js-js-extra script, unfortunately
        FWP.hooks.addFilter('facetwp/template_html', function(resp, params) {

          // Create a temporary div to parse the new HTML response
          let tempContainer = document.createElement('div');
          tempContainer.innerHTML = params.response.template;

          // Find the NEW script element from the AJAX response
          // target #chart-builder-chart-js-js-extra or #chart-builder-charts-google-js-extra but NOT #chart-builder-chart-js-js and #chart-builder-charts-google-js
          const newChartDataElements = tempContainer.querySelectorAll('#chart-builder-chart-js-js-extra, #chart-builder-charts-google-js-extra');

          // also include #chart-builder-inline-css which contains chart specific CSS
          const newChartCssElements = tempContainer.querySelectorAll('#chart-builder-inline-css');

          if (newChartDataElements) {

            newChartDataElements.forEach(function(newScript) {

              const oldChartDataElements = document.getElementById(newScript.id);

              // 1. Remove the old script element from the DOM
              if (oldChartDataElements) {
                oldChartDataElements.remove();
              }

              // 2. Create a brand new script element.
              // Crucial because browsers execute scripts when they are appended
              // as NEWLY created elements, not inserted via innerHTML or when using replaceWith(),
              // which will cause TypeError: _this.dbData is undefined
              const newScriptElement = document.createElement('script');
              newScriptElement.id = newScript.id

              // 4. Copy the JavaScript content (the variable definitions)
              newScriptElement.textContent = newScript.textContent;

              // 5. Append the newly created script element to the document body.
              // This will trigger parsing and executing the script contents,
              // thus defining the new 'aysChartOptions' variables globally.
              document.body.appendChild(newScriptElement);

            });

          }

          if (newChartCssElements) {

            newChartCssElements.forEach(function(newCss) {

              const oldChartCssElements = document.getElementById(newCss.id);

              // 1. Remove the old style element from the DOM
              if (oldChartCssElements) {
                oldChartCssElements.remove();
              }

              // 2. Create a new style element.
              const newInlineCSS = document.createElement('style');
              newInlineCSS.id = newCss.id

              // 4. Copy the CSS content
              newInlineCSS.textContent = newCss.textContent;

              // 5. Append the newly created style element to the document body.
              document.body.appendChild(newInlineCSS);

            });

          }

          return resp;
        }, 1 );

        // Retrigger the charts after a facetwp ajax refresh
        FWP.hooks.addAction('facetwp/loaded', function() {

          if ( FWP.loaded ) { // run only on refresh after first page load

            // Reinitialize JS charts
            if (typeof $.fn.ChartBuilderChartJsMain === 'function') {
              $('.ays-chart-container-chartjs').each(function() {
                try {
                  $(this).ChartBuilderChartJsMain();
                } catch (e) {
                  console.warn('Chart initialization error:', e);
                }
              });
            }

            // Reinitialize Google charts
            if (typeof $.fn.ChartBuilderGoogleChartsMain === 'function') {
              $('.ays-chart-container-google').each(function() {
                try {
                  $(this).ChartBuilderGoogleChartsMain();
                } catch (e) {
                  console.warn('Chart initialization error:', e);
                }
              });
            }

          }

        }, 100);

      }
    })(jQuery);
  </script>
  <?php
}, 100);