<?php
/**
 * File Path: includes/shortcodes/class-mbs-shortcode-genre.php
 *
 * [mbs_genre slug="x"] Shortcode -- SHC-4
 *
 * Renders a single genre's description and book grid inline on any
 * WordPress page. No reading order (genre has none). Layout resolved via
 * MBS_Layout_Registry::resolve_slug_for_term() -- honouring the per-term
 * PRO override or falling back to the global default.
 *
 * Extends MBS_Shortcode_Taxonomy_Base (D-010, Session 117) which handles
 * the shared scaffold: license gate, atts normalisation, slug + term
 * lookup, and the outer div/header HTML.
 *
 * Usage:
 *   [mbs_genre slug="fantasy"]
 *   [mbs_genre slug="fantasy" per_page="10"]
 *   [mbs_genre slug="fantasy" per_page="-1"]   <- show all
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

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

class MBS_Shortcode_Genre extends MBS_Shortcode_Taxonomy_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	protected static function get_taxonomy(): string {
		return MBS_TAX_GENRE;
	}

	protected static function get_shortcode_tag(): string {
		return 'mbs_genre';
	}

	/**
	 * Emit the book grid for the genre term.
	 *
	 * Genre has no reading order; always renders the date-order layout query.
	 *
	 * @param WP_Term $term     The resolved mbs_genre term.
	 * @param int     $per_page Books per page.
	 * @return void
	 */
	protected static function render_body( WP_Term $term, int $per_page ): void {
		$term_id     = (int) $term->term_id;
		// BLK-GENRE-1 / SHC-GENRE-1: Pass 'grid' as the entity default so that
		// Genre behaves consistently with Series, Universe, and Collection (all of
		// which explicitly pass 'grid'). Without this, Genre falls through to the
		// global default_layout setting (which may be 'hero'), causing every book
		// to render as a full-width single-column hero row.
		$layout_slug = MBS_Layout_Registry::resolve_slug_for_term( $term_id, 'grid' );
		$layout_obj  = MBS_Layout_Registry::get_layout( $layout_slug );

		$query = new WP_Query( array(
			'post_type'      => MBS_POST_TYPE,
			'posts_per_page' => $per_page,
			'post_status'    => 'publish',
			'orderby'        => 'date',
			'order'          => 'DESC',
			'no_found_rows'  => true,
			'tax_query'      => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- standard WP query pattern; VIP rule does not apply to this plugin
				array(
					'taxonomy' => MBS_TAX_GENRE,
					'field'    => 'term_id',
					'terms'    => $term_id,
				),
			),
		) );

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted HTML from layout class
		echo $layout_obj->render( $query );
	}
}
