<?php
/**
 * File Path: includes/taxonomies/class-mbs-taxonomy-layout-field-trait.php
 *
 * Taxonomy Layout Field Trait
 *
 * Provides the shared per-term layout override field used by Series, Genre,
 * Universe, and Collection taxonomies. Concrete implementations of
 * render_layout_field(), save_layout_field(), and enqueue_layout_scripts()
 * are consolidated here from four identical copies (DUP-002, Session 136).
 *
 * Using classes must implement layout_taxonomy_key() and may override
 * show_view_button_row() (default true; Genre overrides to false).
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

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

// phpcs:disable WordPress.Security.NonceVerification -- nonce verified in parent class verify_save() / check_admin_referer() before $_POST access; PHPCS cannot trace cross-method nonce verification

/**
 * Shared implementation of the per-term layout override field.
 *
 * @since 1.0.0
 */
trait MBS_Taxonomy_Layout_Field_Trait {

	/**
	 * Return the taxonomy slug constant for this class.
	 *
	 * Must return the taxonomy constant, e.g. MBS_TAX_SERIES.
	 *
	 * @return string
	 */
	abstract protected static function layout_taxonomy_key(): string;

	/**
	 * Whether this taxonomy's term-edit screen shows a 'View ...' button row.
	 *
	 * Defaults to true. Override and return false for taxonomies that have no
	 * settings-notice row (e.g. MBS_Taxonomy_Genre).
	 *
	 * @return bool
	 */
	protected static function show_view_button_row(): bool {
		return true;
	}

	/**
	 * Render the per-term layout selector on the Edit Term screen.
	 *
	 * PRO-gated; no-op on FREE. Shown on edit screen only -- no books exist at
	 * Add Term time so layout choice is premature.
	 * SHC-6: term_meta key mbs_term_layout.
	 *
	 * @param WP_Term $term Current term object.
	 * @return void
	 * @since 1.0.0
	 */
	public static function render_layout_field( WP_Term $term ): void {
		if ( ! mbs_is_pro() ) {
			return;
		}
		$current = (string) get_term_meta( $term->term_id, 'mbs_term_layout', true );
		$layouts = MBS_Layout_Registry::get_archive_layout_options();
		?>
		<tr class="form-field mbs-term-layout-row">
			<th scope="row">
				<label for="mbs_term_layout"><?php esc_html_e( 'Book Grid Layout', 'my-book-showroom' ); ?></label>
			</th>
			<td>
				<select name="mbs_term_layout" id="mbs_term_layout">
					<option value=""><?php esc_html_e( '— Use global default —', 'my-book-showroom' ); ?></option>
					<?php foreach ( $layouts as $slug => $meta ) : ?>
						<option value="<?php echo esc_attr( $slug ); ?>"
							<?php selected( $current, $slug ); ?>
							<?php echo ( ! empty( $meta['pro'] ) ) ? 'data-pro="1"' : ''; ?>>
							<?php echo esc_html( $meta['label'] . ( ! empty( $meta['pro'] ) ? ' (PRO)' : '' ) ); ?>
						</option>
					<?php endforeach; ?>
				</select>
				<div id="mbs-term-layout-desc" class="mbs-layout-description"></div>
				<p class="description">
					<?php esc_html_e( 'Override the global default layout for this term\'s book grid. Leave blank to use the global default from Settings → Formatting.', 'my-book-showroom' ); ?>
				</p>
			</td>
		</tr>
		<?php
	}

	/**
	 * Save the mbs_term_layout term meta when the term is updated.
	 *
	 * PRO-gated; no-op on FREE.
	 *
	 * @param int $term_id Term being saved.
	 * @return void
	 * @since 1.0.0
	 */
	public static function save_layout_field( int $term_id ): void {
		if ( ! mbs_is_pro() ) {
			return;
		}
		if ( ! isset( $_POST['mbs_term_layout'] ) ) {
			return;
		}
		$allowed = array_merge( array( '' ), MBS_Layout_Registry::get_archive_layout_slugs() );
		$layout  = sanitize_key( wp_unslash( $_POST['mbs_term_layout'] ) );
		if ( ! in_array( $layout, $allowed, true ) ) {
			$layout = '';
		}
		update_term_meta( $term_id, 'mbs_term_layout', $layout );
	}

	/**
	 * Enqueue the layout description panel script on the correct term-edit screen.
	 *
	 * Conditionally enqueues the view-button-row mover for taxonomies that show it.
	 * SHC-6: mbs-admin-layout-desc (registered in MBS_Tab_Formatting::enqueue())
	 * is safe to enqueue by handle on any admin page.
	 *
	 * @param string $hook Current admin page hook suffix.
	 * @return void
	 * @since 1.0.0
	 */
	public static function enqueue_layout_scripts( string $hook ): void {
		if ( 'term.php' !== $hook ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( sanitize_key( wp_unslash( $_GET['taxonomy'] ?? '' ) ) !== static::layout_taxonomy_key() ) {
			return;
		}

		if ( static::show_view_button_row() ) {
			// Move the View button row to immediately after the Slug row.
			// WordPress fires _edit_form_fields after the core Description row;
			// JS relocation is the only reliable way to place it near the slug.
			wp_register_script( 'mbs-view-btn-move', false, array(), MBS_VERSION, true );
			wp_enqueue_script( 'mbs-view-btn-move' );
			wp_add_inline_script( 'mbs-view-btn-move', "document.addEventListener('DOMContentLoaded',function(){var v=document.querySelector('tr.mbs-settings-view-row'),s=document.getElementById('slug');if(v&&s){var r=s.closest('tr');if(r&&r.parentNode)r.parentNode.insertBefore(v,r.nextSibling);}});");
		}

		if ( ! mbs_is_pro() ) {
			return;
		}
		wp_enqueue_script( 'mbs-admin-layout-desc' );
		wp_set_script_translations( 'mbs-admin-layout-desc', 'my-book-showroom', MBS_DIR . 'languages' );
		wp_add_inline_script(
			'mbs-admin-layout-desc',
			"jQuery( function() { if ( typeof MBS_LayoutDesc !== 'undefined' ) { MBS_LayoutDesc.init( '#mbs_term_layout', '#mbs-term-layout-desc' ); } } );"
		);
	}
}
