/**
 * Relatedly Frontend — Tracking & Carousel
 *
 * Handles:
 *  - Impression tracking via IntersectionObserver (scroll fallback for older browsers)
 *  - Click tracking via event delegation (single listener on document)
 *  - Carousel prev/next navigation for end-content theme4
 *  - Touch/swipe support for carousel
 *
 * Vanilla JS only — no jQuery dependency.
 *
 * @package Relatedly
 * @since   2.0.0
 */

( function () {
	'use strict';

	// -------------------------------------------------------------------------
	// Impression tracking
	// -------------------------------------------------------------------------

	var trackedImpressions = new Set();

	/**
	 * Send a batched impression request for all tracked links inside a container.
	 * One AJAX request per container (not per post) — audit finding addressed.
	 */
	function trackImpression( container ) {
		var sourcePostId = container.getAttribute( 'data-relatedly-source' );
		var displayType  = container.getAttribute( 'data-relatedly-type' );
		var key          = sourcePostId + '-' + displayType;

		if ( ! sourcePostId || ! displayType || trackedImpressions.has( key ) ) {
			return;
		}

		trackedImpressions.add( key );

		var links = container.querySelectorAll( '.relatedly-tracked-link' );
		var ids   = [];

		links.forEach( function ( link ) {
			var id = link.getAttribute( 'data-relatedly-clicked' );
			if ( id && ids.indexOf( id ) === -1 ) {
				ids.push( id );
			}
		} );

		if ( ! ids.length || typeof relatedlyTracking === 'undefined' ) {
			return;
		}

		// One request per container carrying all post IDs as a comma-separated list.
		sendTrackingRequest( {
			source_post_id:  sourcePostId,
			clicked_post_ids: ids.join( ',' ),
			display_type:    displayType,
			event_type:      'impression',
		} );
	}

	// IntersectionObserver — efficient, fires only when element enters viewport.
	if ( 'IntersectionObserver' in window ) {
		var observer = new IntersectionObserver( function ( entries ) {
			entries.forEach( function ( entry ) {
				if ( entry.isIntersecting ) {
					trackImpression( entry.target );
					observer.unobserve( entry.target );
				}
			} );
		}, { rootMargin: '50px', threshold: 0.1 } );

		document.addEventListener( 'DOMContentLoaded', function () {
			document.querySelectorAll( '[data-relatedly-source]' ).forEach( function ( el ) {
				observer.observe( el );
			} );
		} );

	} else {
		// Scroll fallback for browsers without IntersectionObserver.
		window.addEventListener( 'scroll', function () {
			document.querySelectorAll( '[data-relatedly-source]' ).forEach( function ( el ) {
				var rect = el.getBoundingClientRect();
				if ( rect.top < window.innerHeight && rect.bottom > 0 ) {
					trackImpression( el );
				}
			} );
		}, { once: true } );
	}

	// -------------------------------------------------------------------------
	// Click tracking
	// -------------------------------------------------------------------------

	document.addEventListener( 'click', function ( e ) {
		var link = e.target.closest( '.relatedly-tracked-link' );
		if ( ! link || typeof relatedlyTracking === 'undefined' ) {
			return;
		}

		sendTrackingRequest( {
			source_post_id:  link.getAttribute( 'data-relatedly-source' ),
			clicked_post_ids: link.getAttribute( 'data-relatedly-clicked' ),
			display_type:    link.getAttribute( 'data-relatedly-type' ),
			event_type:      'click',
		} );
	} );

	// -------------------------------------------------------------------------
	// AJAX helper
	// -------------------------------------------------------------------------

	function sendTrackingRequest( params ) {
		if ( typeof XMLHttpRequest === 'undefined' ) {
			return;
		}
		var body = 'action=relatedly_track_event'
			+ '&nonce='           + encodeURIComponent( relatedlyTracking.nonce )
			+ '&source_post_id='  + encodeURIComponent( params.source_post_id || '' )
			+ '&clicked_post_ids='+ encodeURIComponent( params.clicked_post_ids || '' )
			+ '&display_type='    + encodeURIComponent( params.display_type || '' )
			+ '&event_type='      + encodeURIComponent( params.event_type || 'click' );

		var xhr = new XMLHttpRequest();
		xhr.open( 'POST', relatedlyTracking.ajaxUrl, true );
		xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
		xhr.send( body );
	}

	// -------------------------------------------------------------------------
	// Carousel — end-content theme4
	// -------------------------------------------------------------------------

	function getCarouselState( carouselId ) {
		var el      = document.getElementById( carouselId );
		var wrapper = el ? el.querySelector( '.relatedly-carousel-wrapper' ) : null;
		var items   = wrapper ? wrapper.querySelectorAll( '.relatedly-carousel-item' ) : [];
		return { el: el, wrapper: wrapper, items: items };
	}

	function getCurrentX( wrapper ) {
		var t = wrapper.style.transform || 'translateX(0px)';
		var m = t.match( /-?\d+/ );
		return m ? parseInt( m[0], 10 ) : 0;
	}

	window.relatedlyCarouselPrev = function ( carouselId ) {
		var s = getCarouselState( carouselId );
		if ( ! s.wrapper || ! s.items.length ) { return; }
		var itemWidth = s.items[0].offsetWidth + 20;
		var newX      = Math.min( getCurrentX( s.wrapper ) + itemWidth, 0 );
		s.wrapper.style.transform = 'translateX(' + newX + 'px)';
	};

	window.relatedlyCarouselNext = function ( carouselId ) {
		var s        = getCarouselState( carouselId );
		if ( ! s.wrapper || ! s.items.length ) { return; }
		var itemWidth = s.items[0].offsetWidth + 20;
		var maxScroll = -( s.wrapper.scrollWidth - s.el.offsetWidth );
		var newX      = Math.max( getCurrentX( s.wrapper ) - itemWidth, maxScroll );
		s.wrapper.style.transform = 'translateX(' + newX + 'px)';
	};

	// Touch/swipe support for carousel.
	document.addEventListener( 'DOMContentLoaded', function () {
		document.querySelectorAll( '.relatedly-carousel-container' ).forEach( function ( carousel ) {
			var wrapper = carousel.querySelector( '.relatedly-carousel-wrapper' );
			if ( ! wrapper ) { return; }

			var startX = 0;

			carousel.addEventListener( 'touchstart', function ( e ) {
				startX = e.touches[0].clientX;
			}, { passive: true } );

			carousel.addEventListener( 'touchend', function ( e ) {
				var diff = e.changedTouches[0].clientX - startX;
				if ( Math.abs( diff ) < 30 ) { return; }
				var id = carousel.id;
				if ( diff < 0 ) {
					window.relatedlyCarouselNext( id );
				} else {
					window.relatedlyCarouselPrev( id );
				}
			}, { passive: true } );
		} );
	} );

} )();

// -------------------------------------------------------------------------
// Floating Sidebar
// -------------------------------------------------------------------------

( function () {
	'use strict';

	var config   = window.relatedlyFloating;
	var sidebar  = document.querySelector( '.relatedly-floating-sidebar' );

	if ( ! config || ! sidebar ) { return; }

	var DISMISS_KEY = 'relatedly_floating_dismissed_' + config.postId;

	// ---- Dismiss logic ----

	function isDismissed() {
		try {
			var val = sessionStorage.getItem( DISMISS_KEY );
			if ( ! val ) { return false; }
			if ( val === 'permanent' ) { return true; }
			return Date.now() < parseInt( val, 10 );
		} catch ( e ) { return false; }
	}

	function dismiss() {
		try {
			if ( config.dismissBehavior === 'permanent' ) {
				sessionStorage.setItem( DISMISS_KEY, 'permanent' );
			} else {
				// Per-page: hide for this session only.
				sessionStorage.setItem( DISMISS_KEY, String( Date.now() + 86400000 ) );
			}
		} catch ( e ) {
			// Storage can be unavailable in private browsing or strict privacy modes.
		}
		sidebar.classList.add( 'relatedly-hidden' );
	}

	// Close button.
	var closeBtn = sidebar.querySelector( '.relatedly-floating-close' );
	if ( closeBtn ) {
		closeBtn.addEventListener( 'click', dismiss );
	}

	// ---- Show logic ----

	function showSidebar() {
		if ( isDismissed() ) { return; }
		sidebar.classList.remove( 'relatedly-hidden' );
	}

	if ( config.scrollTrigger === 'scroll' ) {
		// Show after user scrolls past configured percentage.
		sidebar.classList.add( 'relatedly-hidden' );
		window.addEventListener( 'scroll', function () {
			var scrolled = ( window.scrollY / ( document.body.scrollHeight - window.innerHeight ) ) * 100;
			if ( scrolled >= config.scrollPct ) {
				showSidebar();
			}
		}, { passive: true } );
	} else {
		showSidebar();
	}

	// ---- Auto-refresh ----

	if ( config.autoRefresh && config.autoRefreshSeconds > 0 ) {
		setInterval( function () {
			if ( typeof XMLHttpRequest === 'undefined' ) { return; }

			var xhr = new XMLHttpRequest();
			xhr.open( 'POST', config.ajaxUrl, true );
			xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
			xhr.onload = function () {
				if ( xhr.status !== 200 ) { return; }
				try {
					var res = JSON.parse( xhr.responseText );
					if ( res.success && res.data.html ) {
						// Replace content but keep the close button.
						var items = sidebar.querySelectorAll( '.relatedly-floating-item' );
						items.forEach( function ( el ) { el.remove(); } );
						sidebar.insertAdjacentHTML( 'beforeend', res.data.html );
					}
				} catch ( e ) {
					// Ignore malformed refresh responses and keep the current sidebar content.
				}
			};
			xhr.send(
				'action=relatedly_floating_sidebar_refresh'
				+ '&nonce='   + encodeURIComponent( config.nonce )
				+ '&post_id=' + encodeURIComponent( config.postId )
			);
		}, config.autoRefreshSeconds * 1000 );
	}

} )();
