( function () {
	if ( 'undefined' === typeof window.wpltaPublic || ! window.fetch ) {
		return;
	}

	var config = window.wpltaPublic;
	var storageKey = 'wplta_session_state';
	var heartbeatMs = Number( config.heartbeatMs || 15000 );
	var sessionTtlMs = Number( config.sessionTtlMs || 1800000 );
	var pageEnteredAt = new Date().toISOString();
	var pageViewId = createId( 'pv' );
	var state = getSessionState();
	var sentInitialView = false;

	state.lastActivity = Date.now();
	persistState( state );

	function createId( prefix ) {
		if ( window.crypto && window.crypto.randomUUID ) {
			return prefix + '-' + window.crypto.randomUUID();
		}

		return prefix + '-' + Date.now() + '-' + Math.random().toString( 16 ).slice( 2 );
	}

	function getSessionState() {
		var raw;

		try {
			raw = window.localStorage.getItem( storageKey );
		} catch ( error ) {
			raw = null;
		}

		if ( raw ) {
			try {
				var parsed = JSON.parse( raw );
				if ( parsed.sessionId && parsed.lastActivity && Date.now() - parsed.lastActivity < sessionTtlMs ) {
					return parsed;
				}
			} catch ( error ) {
				raw = null;
			}
		}

		return {
			sessionId: createId( 'sess' ),
			lastActivity: Date.now()
		};
	}

	function persistState( nextState ) {
		try {
			window.localStorage.setItem( storageKey, JSON.stringify( nextState ) );
		} catch ( error ) {
			return;
		}
	}

	function getPayload( actionType ) {
		return {
			session_id: state.sessionId,
			page_view_id: pageViewId,
			page_url: window.location.href,
			page_title: document.title || '',
			referrer: document.referrer || '',
			time_on_page: Math.max( 0, Math.round( ( Date.now() - new Date( pageEnteredAt ).getTime() ) / 1000 ) ),
			page_entered_at: pageEnteredAt,
			action_type: actionType,
			nonce: config.nonce
		};
	}

	function track( actionType, useBeacon ) {
		state.lastActivity = Date.now();
		persistState( state );

		var payload = getPayload( actionType );

		if ( useBeacon && navigator.sendBeacon ) {
			var beaconPayload = new Blob( [ JSON.stringify( payload ) ], { type: 'application/json' } );
			navigator.sendBeacon( config.restUrl, beaconPayload );
			return;
		}

		window.fetch( config.restUrl, {
			method: 'POST',
			credentials: 'same-origin',
			headers: {
				'Content-Type': 'application/json',
				'X-WP-Nonce': config.nonce
			},
			body: JSON.stringify( payload )
		} ).catch( function () {
			return null;
		} );
	}

	function start() {
		if ( sentInitialView ) {
			return;
		}

		sentInitialView = true;
		track( 'pageview', false );

		window.setInterval( function () {
			track( 'heartbeat', false );
		}, heartbeatMs );
	}

	start();

	window.addEventListener( 'visibilitychange', function () {
		if ( 'hidden' === document.visibilityState ) {
			track( 'leave', true );
		}
	} );

	window.addEventListener( 'pagehide', function () {
		track( 'leave', true );
	} );
}() );
