/**
 * Cache module — Web Vitals RUM (custom, no external lib)
 *
 * Measures LCP, FCP, CLS, INP, TTFB on real visitors using the standard
 * PerformanceObserver APIs and posts each measure (sendBeacon) to the REST
 * endpoint exposed by Cache_WebVitals_Collector.
 *
 * Why custom (no `web-vitals` lib): keep the bundle tiny (~2 KB minified),
 * avoid Apache 2.0 license bookkeeping, full control over what is reported.
 *
 * Sampling: configured server-side (sampleRate 1..100). Devices: derived from
 * pointer + screen width.
 *
 * @package BlaminhorEssentials
 */
(function () {
	'use strict';

	if (typeof window.blaminhorCacheRum === 'undefined') { return; }
	var cfg = window.blaminhorCacheRum;
	if (Math.random() * 100 > cfg.sampleRate) { return; }

	var device = (function () {
		var w = window.innerWidth || document.documentElement.clientWidth;
		if (w < 768) { return 'mobile'; }
		if (w < 1200) { return 'tablet'; }
		return 'desktop';
	})();

	var url = window.location.href.split('#')[0]; // strip hash
	var nav = (function () {
		var entries = performance.getEntriesByType && performance.getEntriesByType('navigation');
		return (entries && entries[0] && entries[0].type) || 'navigate';
	})();

	function rate(metric, value) {
		// Thresholds per https://web.dev/articles/vitals
		switch (metric) {
			case 'LCP':  return value <= 2500 ? 'good' : (value <= 4000 ? 'needs-improvement' : 'poor');
			case 'FCP':  return value <= 1800 ? 'good' : (value <= 3000 ? 'needs-improvement' : 'poor');
			case 'INP':  return value <= 200  ? 'good' : (value <= 500  ? 'needs-improvement' : 'poor');
			case 'CLS':  return value <= 0.1  ? 'good' : (value <= 0.25 ? 'needs-improvement' : 'poor');
			case 'TTFB': return value <= 800  ? 'good' : (value <= 1800 ? 'needs-improvement' : 'poor');
			default:     return '';
		}
	}

	function send(metric, value) {
		var payload = {
			metric: metric,
			value: value,
			rating: rate(metric, value),
			url: url,
			device: device,
			navigation_type: nav
		};
		try {
			var blob = new Blob([JSON.stringify(payload)], { type: 'application/json' });
			if (navigator.sendBeacon) {
				navigator.sendBeacon(cfg.endpoint, blob);
				return;
			}
		} catch (e) { /* fall through */ }
		// Fallback for very old browsers.
		fetch(cfg.endpoint, { method: 'POST', body: JSON.stringify(payload), headers: { 'Content-Type': 'application/json' }, keepalive: true }).catch(function () {});
	}

	/* --------------- LCP --------------- */
	(function () {
		try {
			var lastLcp = 0;
			var po = new PerformanceObserver(function (list) {
				var entries = list.getEntries();
				if (entries.length > 0) { lastLcp = entries[entries.length - 1].renderTime || entries[entries.length - 1].loadTime; }
			});
			po.observe({ type: 'largest-contentful-paint', buffered: true });
			['visibilitychange', 'pagehide'].forEach(function (e) {
				addEventListener(e, function () {
					if (lastLcp > 0 && document.visibilityState === 'hidden') {
						send('LCP', lastLcp);
						po.disconnect();
						lastLcp = 0;
					}
				}, { once: false });
			});
		} catch (e) { /* unsupported */ }
	})();

	/* --------------- FCP --------------- */
	(function () {
		try {
			var po = new PerformanceObserver(function (list) {
				list.getEntries().forEach(function (entry) {
					if (entry.name === 'first-contentful-paint') {
						send('FCP', entry.startTime);
						po.disconnect();
					}
				});
			});
			po.observe({ type: 'paint', buffered: true });
		} catch (e) { /* unsupported */ }
	})();

	/* --------------- TTFB --------------- */
	(function () {
		try {
			var nav = performance.getEntriesByType && performance.getEntriesByType('navigation');
			if (nav && nav[0] && typeof nav[0].responseStart === 'number') {
				send('TTFB', nav[0].responseStart);
			}
		} catch (e) { /* unsupported */ }
	})();

	/* --------------- CLS --------------- */
	(function () {
		try {
			var cls = 0;
			var sessionEntries = [];
			var sessionValue = 0;
			var po = new PerformanceObserver(function (list) {
				list.getEntries().forEach(function (entry) {
					if (entry.hadRecentInput) { return; }
					var firstSessionEntry = sessionEntries[0];
					var lastSessionEntry = sessionEntries[sessionEntries.length - 1];
					if (sessionValue && entry.startTime - lastSessionEntry.startTime < 1000 && entry.startTime - firstSessionEntry.startTime < 5000) {
						sessionValue += entry.value;
						sessionEntries.push(entry);
					} else {
						sessionValue = entry.value;
						sessionEntries = [entry];
					}
					if (sessionValue > cls) { cls = sessionValue; }
				});
			});
			po.observe({ type: 'layout-shift', buffered: true });
			['visibilitychange', 'pagehide'].forEach(function (e) {
				addEventListener(e, function () {
					if (document.visibilityState === 'hidden') {
						send('CLS', cls);
						po.disconnect();
					}
				}, { once: false });
			});
		} catch (e) { /* unsupported */ }
	})();

	/* --------------- INP --------------- */
	(function () {
		try {
			var maxInp = 0;
			var po = new PerformanceObserver(function (list) {
				list.getEntries().forEach(function (entry) {
					if (entry.duration > maxInp) { maxInp = entry.duration; }
				});
			});
			po.observe({ type: 'event', buffered: true, durationThreshold: 16 });
			['visibilitychange', 'pagehide'].forEach(function (e) {
				addEventListener(e, function () {
					if (document.visibilityState === 'hidden' && maxInp > 0) {
						send('INP', maxInp);
						po.disconnect();
						maxInp = 0;
					}
				}, { once: false });
			});
		} catch (e) { /* unsupported */ }
	})();
})();
