(() => {
    const API_URL = 'api/perf-beacon.php';
    const SAMPLE_RATE = 0.2;
    const PAGE = `${location.pathname}${location.search}`;
    const metrics = {
        page: PAGE,
        ts: Date.now(),
        ua: navigator.userAgent,
    };

    if (Math.random() > SAMPLE_RATE) return;

    const rounded = (n) => Math.round(Number(n) || 0);
    const send = () => {
        if (metrics.__sent) return;
        metrics.__sent = true;
        try {
            const body = JSON.stringify(metrics);
            if (navigator.sendBeacon) {
                navigator.sendBeacon(API_URL, new Blob([body], { type: 'application/json' }));
            } else {
                fetch(API_URL, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body,
                    keepalive: true
                }).catch(() => {});
            }
        } catch (_) {}
    };

    // Navigation timing (includes TTFB approximation)
    try {
        const nav = performance.getEntriesByType('navigation')[0];
        if (nav) {
            metrics.ttfb = rounded(nav.responseStart);
            metrics.domContentLoaded = rounded(nav.domContentLoadedEventEnd);
            metrics.loadEvent = rounded(nav.loadEventEnd);
        }
    } catch (_) {}

    // Image transfer stats (for image optimization validation)
    try {
        const resources = performance.getEntriesByType('resource') || [];
        const imageEntries = resources.filter((e) => e && (e.initiatorType === 'img' || /\.(avif|webp|png|jpe?g|gif|svg)(\?|$)/i.test(String(e.name || ''))));
        metrics.imageRequestCount = imageEntries.length;
        metrics.imageTransferBytes = rounded(imageEntries.reduce((sum, e) => sum + Number(e.transferSize || 0), 0));
        metrics.imageDecodedBytes = rounded(imageEntries.reduce((sum, e) => sum + Number(e.decodedBodySize || 0), 0));
    } catch (_) {}

    // FCP
    try {
        const paintEntries = performance.getEntriesByType('paint');
        const fcp = paintEntries.find((e) => e.name === 'first-contentful-paint');
        if (fcp) metrics.fcp = rounded(fcp.startTime);
    } catch (_) {}

    // LCP
    try {
        const lcpObserver = new PerformanceObserver((entryList) => {
            const entries = entryList.getEntries();
            const last = entries[entries.length - 1];
            if (last) metrics.lcp = rounded(last.startTime);
        });
        lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
    } catch (_) {}

    // CLS
    try {
        let clsValue = 0;
        const clsObserver = new PerformanceObserver((entryList) => {
            entryList.getEntries().forEach((entry) => {
                if (!entry.hadRecentInput) clsValue += entry.value;
            });
            metrics.cls = Number(clsValue.toFixed(4));
        });
        clsObserver.observe({ type: 'layout-shift', buffered: true });
    } catch (_) {}

    // INP approximation (event timing)
    try {
        let maxInteraction = 0;
        const inpObserver = new PerformanceObserver((entryList) => {
            entryList.getEntries().forEach((entry) => {
                const latency = (entry.processingEnd || 0) - entry.startTime;
                if (latency > maxInteraction) maxInteraction = latency;
            });
            metrics.inp = rounded(maxInteraction);
        });
        inpObserver.observe({ type: 'event', buffered: true, durationThreshold: 40 });
    } catch (_) {}

    addEventListener('visibilitychange', () => {
        if (document.visibilityState === 'hidden') send();
    });
    addEventListener('pagehide', send);
})();
