<?php

/**
 * Lightweight RUM beacon for INP/CLS/LCP
 *
 * Injects an inline script to collect web vitals and POST to a REST endpoint.
 *
 * @package ProRank\SEO\Frontend
 */

declare(strict_types=1);

namespace ProRank\SEO\Frontend;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}




class RumBeacon {
    public function init(): void {
        add_action( 'wp_head', [ $this, 'output_beacon_script' ], 3 );
    }

    public function output_beacon_script(): void {
        if ( is_admin() || is_user_logged_in() ) {
            return;
        }

        // Use trailing slash to avoid host-level slash redirects converting
        // POST sendBeacon requests into GET (which can surface noisy 404s).
        $endpoint = esc_url_raw( trailingslashit( rest_url( 'prorank-seo/v1/performance/rum' ) ) );
        ?>
        <script>
        (function() {
          if (!('PerformanceObserver' in window)) return;
          let lcp = 0, cls = 0, inp = 0;
          let sent = false;

          try {
            const lcpObs = new PerformanceObserver((list) => {
              const entries = list.getEntries();
              const last = entries[entries.length - 1];
              if (last) lcp = last.renderTime || last.loadTime || last.startTime || 0;
            });
            lcpObs.observe({type:'largest-contentful-paint', buffered:true});
          } catch(e){}

          try {
            const clsObs = new PerformanceObserver((list) => {
              for (const entry of list.getEntries()) {
                if (!entry.hadRecentInput) cls += entry.value || 0;
              }
            });
            clsObs.observe({type:'layout-shift', buffered:true});
          } catch(e){}

          try {
            const inpObs = new PerformanceObserver((list) => {
              for (const entry of list.getEntries()) {
                const dur = entry.duration || entry.processingEnd - entry.startTime || 0;
                if (dur > inp) inp = dur;
              }
            });
            inpObs.observe({type:'event', buffered:true, durationThreshold:0});
          } catch(e){}

          function sendBeacon() {
            if (sent || lcp <= 0) return;
            sent = true;
            const payload = {
              url: location.href,
              lcp: Math.round(lcp),
              cls: Number(cls.toFixed(3)),
              inp: inp > 0 ? Math.round(inp) : null
            };
            const blob = new Blob([JSON.stringify(payload)], {type:'application/json'});
            navigator.sendBeacon('<?php echo esc_js( $endpoint ); ?>', blob);
          }

          document.addEventListener('visibilitychange', () => {
            if (document.visibilityState === 'hidden') {
              sendBeacon();
            }
          });
          window.addEventListener('pagehide', sendBeacon);
        })();
        </script>
        <?php
    }
}
