<?php
/**
 * File Path: layouts/class-mbs-layout-popup.php
 *
 * Popup Layout (PRO)
 *
 * Renders a grid of book thumbnails. Clicking opens a WCAG-compliant modal.
 *
 * Gates:  mbs_is_registered() + mbs_is_pro() (GP-T-1).
 * Output: single .mbs-wrapper (R4 rule).
 * Cover:  MBS_Cover_Renderer::render() for the visible thumbnail (R5 rule).
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class MBS_Layout_Popup implements MBS_Layout { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	/**
	 * Render the popup grid and its shared modal shell.
	 *
	 * @param WP_Query $query   Configured query. Caller has already run query.
	 * @param array    $options Optional render context (layout-specific).
	 * @return string           Escaped HTML output, or empty string on failure.
	 */
	public function render( WP_Query $query, array $options = [] ): string {
		if ( ! mbs_is_registered() ) {
			return '';
		}

		if ( ! mbs_is_pro() ) {
			// SV-16: HTML comment only — no visible element to site visitors (GP-T-3).
			return '<!-- MBS: Popup layout requires PRO license -->';
		}

		if ( ! $query->have_posts() ) {
			return '<p>' . esc_html__( 'No books found.', 'my-book-showroom' ) . '</p>';
		}

		$instance_id = 'mbs-popup-' . wp_unique_id();
		$modal_id    = $instance_id . '-modal';

		ob_start();
		?>
		<div class="mbs-wrapper">
		<div class="mbs-layout mbs-layout-popup" id="<?php echo esc_attr( $instance_id ); ?>">

			<div class="mbs-popup-grid">
				<?php
				while ( $query->have_posts() ) {
					$query->the_post();
					$post_id = get_the_ID();

					// ── Text / taxonomy fields ──────────────────────────────
					// V2-A-004: get_the_terms() reads from WP_Query's pre-warmed term cache (no extra DB query).
					$_mbs_author_terms = get_the_terms( $post_id, MBS_TAX_AUTHOR );
					$author_name       = ( $_mbs_author_terms && ! is_wp_error( $_mbs_author_terms ) ) ? $_mbs_author_terms[0]->name : '';
					$publisher     = get_post_meta( $post_id, 'mbs_publisher',     true );
					$publisher_url = get_post_meta( $post_id, 'mbs_publisher_url', true );
					$pub_date    = get_post_meta( $post_id, 'mbs_pub_date', true );
					$teaser      = get_post_meta( $post_id, 'mbs_teaser', true );

					// ── Format rows (structured, not rendered HTML) ─────────
					$format_rows = MBS_Format_Row_DAO::get_by_post( $post_id );
					$formats     = array();
					foreach ( $format_rows as $row ) {
						if ( ! empty( $row->format ) ) {
							$formats[] = array(
								'format' => ucfirst( sanitize_text_field( $row->format ) ),
								// PLG-028: route through format_price() so symbol and
								// position setting are applied consistently.
								'price'  => ! empty( $row->price )
									? MBS_Formatting::format_price( (float) $row->price )
									: '',
							);
						}
					}

					// ── F-005: Cover as structured data (URL + alt text) ────
					// MBS_Cover_Renderer::render() is still used for the visible
					// button thumbnail (echoed directly — not injected via JS).
					// The data-book attribute receives only the image URL and alt
					// text so the modal JS can construct a safe <img> node.
					$cover_thumb_id = get_post_thumbnail_id( $post_id ); // R5-exempt: cover URL/alt for JS modal data-book payload, display handled by MBS_Cover_Renderer::render() above
					$cover_url_src  = $cover_thumb_id
						? wp_get_attachment_image_url( $cover_thumb_id, 'medium' ) // R5-exempt: cover URL/alt for JS modal data-book payload, display handled by MBS_Cover_Renderer::render() above
						: '';
					$cover_url      = $cover_url_src ? esc_url_raw( $cover_url_src ) : '';
					$cover_alt      = sanitize_text_field( get_the_title() );

					// ── F-005: Buy links as structured data ({url, label}[]) ─
					// MBS_Buy_Link_Renderer::render_order_now() is no longer called
					// here. Raw link objects are fetched and mapped to a sanitized
					// {url, label} array for safe JS-side DOM construction.
					$raw_links = MBS_Buy_Link_Renderer::get_buy_links( $post_id );
					$buy_links = array();
					foreach ( $raw_links as $link_obj ) {
						$link_url = esc_url_raw( $link_obj->url ?? '' );
						if ( ! $link_url ) {
							continue;
						}
						$buy_links[] = array(
							'url'   => $link_url,
							'label' => sanitize_text_field( $link_obj->label ?? '' ),
						);
					}

					// ── Assemble structured data payload ────────────────────
					$popup_data = array(
						'title'     => sanitize_text_field( get_the_title() ),
						'link'      => esc_url_raw( get_permalink() ),
						'author'    => sanitize_text_field( $author_name ),
						'publisher'     => sanitize_text_field( $publisher ),
						'publisher_url' => esc_url_raw( $publisher_url ),
						'pub_date'  => sanitize_text_field( $pub_date ),
						'teaser'    => sanitize_textarea_field( $teaser ),
						'formats'   => $formats,
						'cover_url' => $cover_url,
						'cover_alt' => $cover_alt,
						'buy_links' => $buy_links,
					);

					// Render the visible thumbnail for the grid button.
					$cover_html = MBS_Cover_Renderer::render( $post_id );
					?>
					<button type="button"
					        class="mbs-popup-trigger mbs-book-card"
					        data-popup-id="<?php echo esc_attr( $modal_id ); ?>"
					        data-book="<?php echo esc_attr( wp_json_encode( $popup_data ) ); ?>"
					        aria-haspopup="dialog"
					        aria-label="<?php echo esc_attr(
					            sprintf(
					                /* translators: %s: book title */
					                __( 'View details for %s', 'my-book-showroom' ),
					                get_the_title()
					            )
					        ); ?>">
						<?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						// -- trusted HTML from MBS_Cover_Renderer::render(); not user input.
						echo $cover_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted renderer returns pre-escaped HTML
						?>
						<span class="mbs-popup-title-hint"><?php echo esc_html( get_the_title() ); ?></span>
					</button>
					<?php
				}
				wp_reset_postdata();
				?>
			</div>

			<!-- Modal shell — populated by mbs-layout-popup.js (REF-36) using structured data-book payload -->
			<div id="<?php echo esc_attr( $modal_id ); ?>"
			     class="mbs-popup-modal"
			     role="dialog"
			     aria-modal="true"
			     aria-labelledby="<?php echo esc_attr( $modal_id ); ?>-title"
			     hidden>
				<div class="mbs-popup-overlay" data-close="1"></div>
				<div class="mbs-popup-dialog">
					<button type="button"
					        class="mbs-popup-close"
					        aria-label="<?php esc_attr_e( 'Close book details', 'my-book-showroom' ); ?>">
						&times;
					</button>
					<div class="mbs-popup-body">
						<div class="mbs-popup-cover"></div>
						<div class="mbs-popup-details">
							<h2 class="mbs-popup-book-title" id="<?php echo esc_attr( $modal_id ); ?>-title"></h2>
							<p class="mbs-popup-author"></p>
							<p class="mbs-popup-meta"></p>
							<p class="mbs-popup-teaser"></p>
							<ul class="mbs-popup-formats"></ul>
							<div class="mbs-popup-buy-links"></div>
							<a class="mbs-popup-full-link button" href="#">
								<?php esc_html_e( 'View full page →', 'my-book-showroom' ); ?>
							</a>
						</div>
					</div>
				</div>
			</div>
		</div>
		</div>
		<?php
		return ob_get_clean();
	}
}
