/**
 * Cart Preview Recommendations Integration
 *
 * Hooks into the cart preview to display product recommendations.
 *
 * @package EDD\Pro\Recommendations
 * @since   3.6.2
 */

import shadowStyles from '!!to-string-loader!css-loader!postcss-loader!sass-loader!./recommendations/_recommendations.scss';

/**
 * Initialize Cart Preview Recommendations Integration
 */
function initializeRecommendationsIntegration() {

	/**
	 * Setup hooks when API is available
	 *
	 * @param {Object} api Cart preview API
	 */
	function setupHooks( api ) {

		// Inject recommendations styles into Shadow DOM
		injectStyles( api );

		/**
		 * Render recommendations after cart items are rendered
		 *
		 * Displays product recommendations with ability to add to cart.
		 *
		 * @param {Object} cartData Full cart data from API response
		 */
		api.hooks.addAction( 'afterRenderItems', function ( cartData ) {
			const recommendationsContainer = getRecommendationsContainer( api );
			if ( ! recommendationsContainer ) {
				return;
			}

			const recommendations = cartData.recommendations || [];
			if ( ! recommendations || recommendations.length === 0 ) {
				recommendationsContainer.classList.add( 'hidden' );
				return;
			}

			renderRecommendations( api, recommendationsContainer, recommendations );
			recommendationsContainer.classList.remove( 'hidden' );
		} );
	}

	/**
	 * Render recommendations
	 *
	 * @param {Object} api Cart preview API
	 * @param {HTMLElement} container Recommendations container
	 * @param {Array} recommendations Array of recommendations
	 */
	function renderRecommendations( api, container, recommendations ) {
		const listElement = container.querySelector( '.cart-preview-recommendations__list' );
		if ( ! listElement ) {
			return;
		}

		// Clear existing recommendations
		listElement.innerHTML = '';

		for ( const recommendation of recommendations ) {
			const item = createRecommendationElement( api, recommendation );
			listElement.appendChild( item );
		}
	}

	/**
	 * Create a recommendation element
	 *
	 * @param {Object} api Cart preview API
	 * @param {Object} recommendation Recommendation data
	 * @return {HTMLElement} Recommendation element
	 */
	function createRecommendationElement( api, recommendation ) {
		// Get the recommendation template
		const template = document.getElementById( 'edd-cart-preview-recommendation-template' );
		if ( ! template ) {
			console.error( 'EDD Recommendations: Template not found' );
			return document.createElement( 'div' );
		}

		// Clone the template
		const itemClone = document.importNode( template.content, true );

		// Get the container element
		const item = itemClone.querySelector( '.cart-preview-recommendation' );
		const image = itemClone.querySelector( '.cart-preview-recommendation__image' );
		const title = itemClone.querySelector( '.cart-preview-recommendation__title a' );
		const price = itemClone.querySelector( '.cart-preview-recommendation__price' );
		const addButton = itemClone.querySelector( '.cart-preview-recommendation__button' );

		// Populate with recommendation data
		item.dataset.productId = recommendation.product_id;
		addButton.dataset.productId = recommendation.product_id;
		addButton.setAttribute( 'aria-label', globalThis.eddRecommendationsPreview.i18n.addItemLabel.replace( '%s', recommendation.title ) );

		// Handle thumbnail
		if ( recommendation.thumbnail ) {
			image.src = recommendation.thumbnail;
			image.alt = recommendation.title;
			image.style.display = '';
		}

		// Set text content (automatically escapes HTML)
		title.textContent = recommendation.title;
		title.href = recommendation.url;
		price.innerHTML = recommendation.price; // Price is already formatted/escaped by server

		// Add click handler for the add to cart button
		addButton.addEventListener( 'click', function ( e ) {
			e.preventDefault();
			handleAddToCart( api, recommendation );
		} );

		return itemClone;
	}

	/**
	 * Handle add to cart for a recommendation
	 *
	 * @param {Object} api Cart preview API
	 * @param {Object} recommendation Recommendation data
	 */
	async function handleAddToCart( api, recommendation ) {
		// Get current state for token/timestamp
		const state = api.getState();

		// Disable the button and show loading state (search in Shadow DOM)
		const hostElement = document.querySelector( 'edd-cart-preview' );
		const button = hostElement?.shadowRoot
			? hostElement.shadowRoot.querySelector( `.cart-preview-recommendation__button[data-product-id="${recommendation.product_id}"]` )
			: null;

		if ( button ) {
			button.disabled = true;
		}

		try {
			const response = await fetch( `${globalThis.eddCartPreviewConfig.apiBase}/add`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
					'X-EDD-Cart-Token': state.token,
					'X-EDD-Cart-Timestamp': globalThis.eddCartPreviewConfig.timestamp,
					'X-Wp-Nonce': globalThis.eddCartPreviewConfig.nonce
				},
				body: JSON.stringify( {
					download_id: recommendation.product_id,
					options: {
						recommendation: true
					}
				} )
			} );

			if ( ! response.ok ) {
				throw new Error( 'Failed to add item to cart' );
			}

			// Parse the JSON response body
			const data = await response.json();

			// Manually refresh the cart preview with the new data
			// We don't trigger the jQuery event to avoid compatibility issues
			// with legacy code expecting a different response format
			await api.refresh();

			const statusElement = hostElement?.shadowRoot?.querySelector( '[data-edd-cart-status]' );
			if ( statusElement && data?.addedToCart ) {
				statusElement.textContent = data.addedToCart;
			}
		} catch ( error ) {
			console.error( 'EDD Recommendations: Add to cart failed', error );
			// Re-enable button on error
			if ( button?.isConnected ) {
				button.disabled = false;
			}
		}
	}

	// Check if cart preview API is already available
	if ( globalThis.eddSlideoutCart?.hooks ) {
		setupHooks( globalThis.eddSlideoutCart );
	} else {
		// API not ready yet, wait for the event
		document.addEventListener( 'edd:cart-preview:ready', ( event ) => {
			setupHooks( event.detail.api );
		} );
	}
}

/**
 * Inject recommendations styles into Shadow DOM
 *
 * @param {Object} api Cart preview API
 */
function injectStyles ( api ) {
	const hostElement = document.querySelector( 'edd-cart-preview' );
	if ( ! hostElement?.shadowRoot ) {
		return;
	}

	// Check if styles already injected
	if ( hostElement.shadowRoot.querySelector( '#edd-recommendations-styles' ) ) {
		return;
	}

	const style = document.createElement( 'style' );
	style.id = 'edd-recommendations-styles';
	style.textContent = shadowStyles;

	hostElement.shadowRoot.appendChild( style );
}

/**
 * Get the recommendations container element from Shadow DOM
 *
 * @param {Object} api Cart preview API
 * @return {HTMLElement|null} Recommendations container element
 */
function getRecommendationsContainer ( api ) {
	// Access the shadow root through the host element
	const hostElement = document.querySelector( 'edd-cart-preview' );
	if ( ! hostElement?.shadowRoot ) {
		return null;
	}

	return hostElement.shadowRoot.querySelector( '.cart-preview-recommendations' );
}

// Initialize when DOM is ready
if ( document.readyState === 'loading' ) {
	document.addEventListener( 'DOMContentLoaded', initializeRecommendationsIntegration );
} else {
	initializeRecommendationsIntegration();
}
