<?php
/**
 * File Path: includes/taxonomies/class-mbs-taxonomy-universe.php
 *
 * Universe / Shared World Taxonomy — My Book Showroom
 *
 * Registers the mbs_universe taxonomy for grouping books into shared fictional
 * cosmoses (e.g. Cosmere, Grishaverse, The Expanse, Warhammer 40k, Star Wars EU).
 * Many-to-many, non-hierarchical (flat). Sub-universes deferred.
 *
 * PRO-gated: the default WordPress tag-style sidebar widget is suppressed on the
 * book editor and replaced by MBS_Metabox_Universe, which enforces the PRO gate
 * and the opt-in toggle (mbs_setting_advanced_universe_enabled).
 *
 * Opt-in: even PRO users must enable Universe via Settings → Advanced before the
 * metabox and front-end display appear. Default: disabled.
 *
 * Display stacking order (F-017, locked 2026-04-22):
 *   Series (with position) → Universe (subtle secondary text) → Collections → Genre/Tag
 *
 * See BACKLOG F-017.
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Taxonomies
 * @since      1.0.0
 */

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

class MBS_Taxonomy_Universe {
	use MBS_Taxonomy_Layout_Field_Trait;

	/**
	 * Return the taxonomy constant for the layout field trait.
	 *
	 * @return string
	 */
	protected static function layout_taxonomy_key(): string {
		return MBS_TAX_UNIVERSE;
	}

	public static function register(): void {
		$labels = array(
			'name'              => __( 'Universes', 'my-book-showroom' ),
			'singular_name'     => __( 'Universe', 'my-book-showroom' ),
			'menu_name'         => __( 'Universes', 'my-book-showroom' ),
			'all_items'         => __( 'All Universes', 'my-book-showroom' ),
			'add_new_item'      => __( 'Add New Universe', 'my-book-showroom' ),
			'new_item_name'     => __( 'New Universe Name', 'my-book-showroom' ),
			'edit_item'         => __( 'Edit Universe Slug', 'my-book-showroom' ),
			'update_item'       => __( 'Update Universe', 'my-book-showroom' ),
			'search_items'      => __( 'Search Universes', 'my-book-showroom' ),
			'not_found'         => __( 'No universes found.', 'my-book-showroom' ),
			'no_terms'          => __( 'No universes', 'my-book-showroom' ),
		);

		register_taxonomy(
			MBS_TAX_UNIVERSE,
			MBS_POST_TYPE,
			array(
				'labels'            => $labels,
				'hierarchical'      => false,
				'public'            => true,
				'show_ui'           => true,
				'show_in_rest'      => true,
				'show_admin_column' => false, // metabox-only; no column clutter
				// MENU-01 pattern: MBS_Admin::add_menu() registers the Universes submenu
				// when the toggle is on. Suppressed here to avoid a bare WP menu entry
				// that bypasses the PRO + opt-in checks.
				'show_in_menu'          => false,
				'show_in_quick_edit'    => false,
				// RF-013: Count all non-trashed statuses, not just published (latent bug fix).
				'update_count_callback' => array( __CLASS__, 'update_term_count_all' ),
			)
		);

		// Suppress the default tag-style sidebar widget on the book editor.
		// MBS_Metabox_Universe renders a custom PRO-gated multi-select instead.
		add_action( 'add_meta_boxes', array( __CLASS__, 'remove_default_meta_box' ), 99 );
		if ( is_admin() ) {
			add_action( MBS_TAX_UNIVERSE . '_edit_form_fields', array( __CLASS__, 'render_settings_notice' ),  5, 2 );
			add_action( MBS_TAX_UNIVERSE . '_edit_form_fields', array( __CLASS__, 'render_layout_field' ), 20, 2 );
			add_action( 'edited_' . MBS_TAX_UNIVERSE,           array( __CLASS__, 'save_layout_field' ) );
			add_action( 'admin_enqueue_scripts',                array( __CLASS__, 'enqueue_layout_scripts' ) );
		}
	}

	/**
	 * Render a navigation notice on the native WordPress Edit Term screen.
	 *
	 * Points editors to Settings → Universes for the full rich editing UI.
	 * Delegates HTML rendering to MBS_Taxonomy_Settings_Notice::render().
	 *
	 * @param WP_Term $term Current term object.
	 * @return void
	 * @since 1.0.0
	 */
	public static function render_settings_notice( WP_Term $term ): void {
		MBS_Taxonomy_Settings_Notice::render(
			$term,
			'universes',
			/* translators: Button label linking to the universes front-end page. */
			__( 'View Universe →', 'my-book-showroom' ),
			/* translators: %s: link to My Book Showroom → Settings → Universes */
			__( 'To edit the description, banner, and other details, go to %s. This screen manages the slug only.', 'my-book-showroom' ),
			__( 'My Book Showroom → Settings → Universes', 'my-book-showroom' )
		);
	}
	public static function remove_default_meta_box(): void {
		remove_meta_box( 'tagsdiv-' . MBS_TAX_UNIVERSE, MBS_POST_TYPE, 'side' );
	}
	/**
	 * Term count callback: count all non-trashed post statuses.
	 *
	 * WordPress core's _update_post_term_count() only counts published posts.
	 * This callback counts every non-trashed status so term counts stay accurate
	 * during active editing (drafts, private, pending, future).
	 *
	 * Registered via 'update_count_callback' on all four MBS taxonomies
	 * (RF-013: fixes the latent bug where genre/series/universe showed 0 for
	 * non-published books).
	 *
	 * @param int[]       $terms    Array of term taxonomy IDs to update.
	 * @param WP_Taxonomy $taxonomy Taxonomy object (unused; required by WP).
	 * @return void
	 */
	public static function update_term_count_all( array $terms, WP_Taxonomy $taxonomy ): void {
		foreach ( $terms as $ttid ) {
			MBS_Taxonomy_Count_DAO::update_term_book_count( (int) $ttid );
		}
	}

}
