/**
 * Shared Alpine helper components for the AffiliateWP admin.
 *
 * Home for globally-registered `Alpine.data` components that aren't tied to a
 * single screen. Enqueued on every AffiliateWP admin page.
 *
 * @since 2.33.0
 */

/* global Alpine */

document.addEventListener( 'alpine:init', () => {
	/**
	 * Scroll-shadow component for horizontally-scrollable containers.
	 *
	 * Tracks whether the scroller has more content off either edge and
	 * exposes `scrollLeft` / `scrollRight` booleans. Pair with two
	 * absolutely-positioned overlay elements gated on those booleans to
	 * render Stripe-style edge fades that disappear when the user reaches
	 * the start/end.
	 *
	 * Markup contract:
	 *  - The component root carries `x-data="affwpScrollShadow"` and is
	 *    positioned relative.
	 *  - The scrolling element inside carries `x-ref="scroller"` and the
	 *    overflow-x-auto utility.
	 *
	 * @since 2.33.0
	 */
	Alpine.data( 'affwpScrollShadow', () => ( {
		scrollLeft: false,
		scrollRight: false,
		/*
		 * Height of the horizontal scrollbar gutter, so edge-fade overlays stop
		 * above it. 0 on overlay-scrollbar platforms (macOS), ~15px with classic scrollbars.
		 */
		scrollbarH: 0,
		/*
		 * Right edge (px from the table's left) of the frozen sticky-left column group,
		 * so the left edge-fade sits at that seam. 0 when no columns are frozen.
		 */
		frozenLeftW: 0,

		init() {
			const el = this.$refs.scroller;

			if ( ! el ) {
				return;
			}

			// Tables freezing leading columns declare them via data-freeze-cols (space-separated keys).
			const freezeCols = ( el.dataset.freezeCols || '' ).trim().split( /\s+/ ).filter( Boolean );

			const update = () => {
				this.scrollLeft  = el.scrollLeft > 0;
				this.scrollRight = Math.ceil( el.scrollLeft + el.clientWidth ) < el.scrollWidth;
				this.scrollbarH  = el.offsetHeight - el.clientHeight;

				if ( freezeCols.length ) {
					/*
					 * Publish each frozen column's left offset (running width of prior columns)
					 * as a CSS var the sticky rules read. The accumulated total is the frozen
					 * group's right edge, where the left edge-fade sits. WP's header cb is a
					 * <td>, every other header cell a <th>.
					 */
					let cum = 0;
					freezeCols.forEach( ( col ) => {
						el.style.setProperty( '--affwp-freeze-' + col + '-left', cum + 'px' );
						const cell = el.querySelector( 'thead .column-' + col );
						if ( cell ) {
							cum += cell.offsetWidth;
						}
					} );
					this.frozenLeftW = cum;
				}
			};

			el.addEventListener( 'scroll', update, { passive: true } );
			new ResizeObserver( update ).observe( el );

			this.$nextTick( update );
		},
	} ) );
} );
