/**
 * @file assets/js/mbs-front-order-now.js
 * Order Now button toggle (accordion) and catalog modal.
 *
 * F-003: Buy-link injection uses DOM construction (createElement + textContent)
 * rather than template-literal string concatenation + innerHTML/.html().
 * This is XSS-safe regardless of upstream PHP sanitization state.
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

/* global jQuery */

( function( MBS, $, undefined ) {
	'use strict';
	var __ = wp.i18n.__;
	var sprintf = wp.i18n.sprintf;

	/**
	 * Handles the Order Now button toggle (accordion) and catalog modal.
	 *
	 * @namespace MBS.OrderNow
	 */
	MBS.OrderNow = {

		/**
		 * Bind click handlers for accordion toggle and catalog modal open.
		 *
		 * @return {void}
		 */
		init: function() {
			$( document ).on( 'click', '.mbs-order-now-btn',     this.toggleBuyLinks );
			$( document ).on( 'click', '.mbs-order-now-catalog', this.openModal );
		},

		/**
		 * Toggle the retailer button accordion on the single-page view.
		 *
		 * @param {jQuery.Event} e Click event.
		 * @return {void}
		 */
		toggleBuyLinks: function( e ) {
			e.preventDefault();

			var $btn   = $( this );
			var $links = $btn.siblings( '.mbs-retailer-buttons' );

			if ( $links.hasClass( 'active' ) ) {
				$links.removeClass( 'active' );
				$btn.removeClass( 'active' );
			} else {
				$links.addClass( 'active' );
				$btn.addClass( 'active' );
			}
		},

		/**
		 * Open the purchase options modal for a catalog card.
		 *
		 * Creates a WCAG-compliant dialog with focus trap and keyboard dismissal.
		 * Buy links are injected via DOM construction -- never innerHTML or .html().
		 *
		 * @param {jQuery.Event} e Click event.
		 * @return {void}
		 */
		openModal: function( e ) {
			e.preventDefault();

			var $button   = $( this );
			var bookTitle = $button.closest( '.mbs-book-card' ).find( '.mbs-book-title' ).text() || __( 'this book', 'my-book-showroom' );

			// Guard: only one modal at a time.
			if ( $( '#mbs-order-modal' ).length ) {
				return;
			}

			// ---- Build modal scaffold via DOM ----
			var modal    = document.createElement( 'div' );
			var content  = document.createElement( 'div' );
			var closeBtn = document.createElement( 'button' );
			var heading  = document.createElement( 'h2' );
			var linkWrap = document.createElement( 'div' );

			modal.id        = 'mbs-order-modal';
			modal.className = 'mbs-modal';
			modal.setAttribute( 'role', 'dialog' );
			modal.setAttribute( 'aria-modal', 'true' );
			modal.setAttribute( 'aria-labelledby', 'mbs-modal-title' );

			content.className = 'mbs-modal-content';

			closeBtn.type      = 'button';
			closeBtn.className = 'mbs-modal-close';
			closeBtn.setAttribute( 'aria-label', __( 'Close modal', 'my-book-showroom' ) );
			closeBtn.textContent = '\u00D7'; // ×

			heading.id          = 'mbs-modal-title';
			heading.textContent = sprintf( __( 'Purchase options for %s', 'my-book-showroom' ), bookTitle );

			linkWrap.className = 'mbs-modal-buy-links';

			content.appendChild( closeBtn );
			content.appendChild( heading );
			content.appendChild( linkWrap );
			modal.appendChild( content );
			document.body.appendChild( modal );

			var $modal    = $( modal );
			var $content  = $( content );
			var $closeBtn = $( closeBtn );
			var $linkWrap = $( linkWrap );

			// ---- Populate buy links -- F-003: DOM construction, no innerHTML ----
			var linksData = $button.data( 'mbs-buy-links' );

			if ( linksData && linksData.length ) {
				$.each( linksData, function( i, link ) {
					var a         = document.createElement( 'a' );
					a.href        = link.url || '#';
					a.textContent = link.label || __( 'Buy Now', 'my-book-showroom' );
					a.className   = 'mbs-retailer-btn';
					a.target      = '_blank';
					a.rel         = 'noopener';
					$linkWrap.append( a );
				} );
			} else {
				var p         = document.createElement( 'p' );
				p.className   = 'mbs-modal-note';
				p.textContent = __( 'No purchase links available for this format.', 'my-book-showroom' );
				$linkWrap.append( p );
			}

			// ---- Focus trap ----
			var focusableSelectors = 'a[href], button, [tabindex]:not([tabindex="-1"])';

			/**
			 * Re-collect focusable elements after dynamic content changes.
			 *
			 * @return {jQuery} Updated collection of focusable elements.
			 */
			var getFocusables = function() {
				return $content.find( focusableSelectors ).filter( ':visible' );
			};

			// ---- Event handlers ----

			/**
			 * Remove modal from DOM and return focus to the triggering button.
			 *
			 * @return {void}
			 */
			var closeModal = function() {
				$modal.remove();
				$button.focus();
				$( document ).off( 'keydown.mbs-modal' );
			};

			$closeBtn.on( 'click', closeModal );

			$modal.on( 'click', function( evt ) {
				if ( evt.target === modal ) {
					closeModal();
				}
			} );

			$( document ).on( 'keydown.mbs-modal', function( evt ) {
				if ( ! $modal.length ) {
					return;
				}

				if ( evt.key === 'Escape' ) {
					closeModal();
					return;
				}

				if ( evt.key === 'Tab' ) {
					var $focusables = getFocusables();
					var $first      = $focusables.first();
					var $last       = $focusables.last();

					if ( evt.shiftKey ) {
						if ( document.activeElement === $first[ 0 ] ) {
							evt.preventDefault();
							$last.focus();
						}
					} else {
						if ( document.activeElement === $last[ 0 ] ) {
							evt.preventDefault();
							$first.focus();
						}
					}
				}
			} );

			$modal.show();
			$closeBtn.focus();
		}
	};

	MBS.register( function() {
		MBS.OrderNow.init();
	} );

} )( window.MBS = window.MBS || {}, jQuery );
