<?php
/**
 * File Path: includes/shortcodes/class-mbs-shortcode-series.php
 *
 * [mbs_series slug="x"] Shortcode -- SHC-1
 *
 * Renders a single series description, optional PRO banner, and book grid
 * inline, without calling get_header() / get_footer(). Feature-for-feature
 * equivalent of taxonomy-mbs-series.php.
 *
 * Sprint BACK-SC-001: Rendering delegated to MBS_Archive_Reader::render_ordered().
 * Display mode resolved via MBS_Archive_Reader::resolve_display_mode() from
 * per-term meta, global option, and toggle gate. PRO gate applied inside
 * render_ordered():
 *   - Series Order (order)                -- FREE.
 *   - Reading Order (reading_order / both) -- PRO.
 *
 * 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.
 *
 * Attributes:
 *   slug     (string, required) -- term slug for mbs_series
 *   per_page (int, default 20)  -- reserved; ignored by render_ordered().
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

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

class MBS_Shortcode_Series 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_SERIES;
	}

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

	/**
	 * F-011: Series banner image -- PRO only.
	 *
	 * Inserted after </header> and before the book grid.
	 *
	 * @param WP_Term $term The resolved mbs_series term.
	 * @return void
	 */
	protected static function render_after_header( WP_Term $term ): void {
		if ( ! mbs_is_pro() && ! mbs_is_pub() ) {
			return;
		}
		$banner_id = (int) get_term_meta( (int) $term->term_id, 'mbs_series_banner_id', true );
		if ( ! $banner_id ) {
			return;
		}
		?>
		<div class="mbs-series-banner">
			<?php echo wp_get_attachment_image( // R5-exempt: series banner image, not book cover
				$banner_id,
				'full',
				false,
				array(
					'class' => 'mbs-series-banner-img',
					'alt'   => $term->name,
				)
			); ?>
		</div>
		<?php
	}

	/**
	 * Render the book grid for the series term.
	 *
	 * Sprint BACK-SC-001: Delegates to MBS_Archive_Reader::render_ordered().
	 * CE-2 removed: Reading Order is PRO-gated (enforced inside render_ordered()).
	 * Series Order (release order) is FREE for all tiers.
	 *
	 * @param WP_Term $term     The resolved mbs_series term.
	 * @param int     $per_page Reserved; ignored by render_ordered().
	 * @return void
	 */
	protected static function render_body( WP_Term $term, int $per_page ): void {
		$term_id = (int) $term->term_id;

		$display_mode = MBS_Archive_Reader::resolve_display_mode(
			$term_id,
			'mbs_series_archive_display_mode',
			'mbs_setting_series_archive_display_mode',
			'mbs_setting_show_series_reading_order'
		);

		$layout_slug = MBS_Layout_Registry::resolve_slug_for_term( $term_id, 'grid' );
		$layout_obj  = MBS_Layout_Registry::get_layout( $layout_slug );

		$html = MBS_Archive_Reader::render_ordered(
			MBS_Series_Reading_Order_DAO::class,
			$term_id,
			$layout_obj,
			$layout_slug,
			array(
				'display_mode'  => $display_mode,
				'merge_missing' => false,
				'context'       => 'series',
			)
		);

		if ( '' === $html ) {
			echo '<p>' . esc_html__( 'No books found in this series.', 'my-book-showroom' ) . '</p>';
			return;
		}

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $html;
	}
}
