<?php
/**
 * File Path: includes/admin/tabs/authors-series/class-mbs-tab-universes-render.php
 *
 * Universes Tab -- Render Class
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Admin/Tabs/Authors-Series
 * @since      1.0.0
 */

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

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

	/**
	 * Render the Universes tab.
	 *
	 * Outputs the tab wrapper, an optional toggle-disabled notice, a PRO gate
	 * message for FREE installs, the success notice (when redirected after
	 * save), and one <form>-wrapped <details> card per universe term.
	 *
	 * @return void
	 */
	public static function render(): void {
		$updated  = isset( $_GET['updated'] ) && '1' === $_GET['updated']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$saved_id = isset( $_GET['saved'] ) ? absint( $_GET['saved'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		$toggle_on = (int) get_option( 'mbs_setting_advanced_universe_enabled', 0 );

		// F-SORT-2: per-user sort preference.
		$sort_pref = (string) get_user_meta( get_current_user_id(), 'mbs_sort_pref_universes', true );
		if ( ! in_array( $sort_pref, array( 'name', 'name_sort' ), true ) ) {
			$sort_pref = 'name';
		}
		?>
		<div class="mbs-tab-universes">

			<?php MBS_Tab_Catalog_Subnav::render( 'universes' ); // UX-NAV-001 ?>

			<h2><?php esc_html_e( 'Universes', 'my-book-showroom' ); ?><?php mbs_help_tip(
				__( 'A Universe is a shared world or continuity that spans multiple Series and standalone books. Use it when your stories are set in the same world but don\'t belong to a single series — the Universe groups them by world, not by sequence.', 'my-book-showroom' ),
				__( 'What is a Universe?', 'my-book-showroom' ),
				'mbs-help-tip--wide'
			); ?></h2>
			<p class="mbs-settings-subtitle">
				<?php esc_html_e( 'Extended fields and reading-order management for each universe. Click a row to expand and edit.', 'my-book-showroom' ); ?>
			</p>

			<?php if ( ! $toggle_on ) : ?>
				<div class="notice notice-warning inline">
					<p>
						<?php esc_html_e( 'The Universe feature is currently disabled. Enable it under Settings → Advanced / Developer → Universe / Shared World.', 'my-book-showroom' ); ?>
					</p>
				</div>
			<?php elseif ( ! mbs_is_pro() ) : ?>
				<div class="notice notice-info inline">
					<p>
						<?php esc_html_e( 'Universe reading order requires a PRO license. Upgrade to set and display custom reading sequences for your universes.', 'my-book-showroom' ); ?>
					</p>
				</div>
				<!-- MBS: Universe reading order requires PRO license -->
			<?php else : ?>
				<?php
				$universes = get_terms( array(
					'taxonomy'   => MBS_TAX_UNIVERSE,
					'hide_empty' => false,
					'orderby'    => 'name',
					'order'      => 'ASC',
				) );

				// F-SORT-2: when name_sort, re-sort by mbs_sort_key (article-stripped).
				if ( ! is_wp_error( $universes ) && 'name_sort' === $sort_pref ) {
					usort( $universes, function ( $a, $b ) {
						$ka = (string) get_term_meta( $a->term_id, 'mbs_sort_key', true );
						if ( '' === $ka ) { $ka = mbs_compute_sort_key( $a->name ); }
						$kb = (string) get_term_meta( $b->term_id, 'mbs_sort_key', true );
						if ( '' === $kb ) { $kb = mbs_compute_sort_key( $b->name ); }
						return strcmp( $ka, $kb );
					} );
				}

				// Group universes by first letter; non-alpha names go under '#'.
				$grouped = array();
				if ( ! is_wp_error( $universes ) && ! empty( $universes ) ) {
					foreach ( $universes as $u ) {
						if ( 'name_sort' === $sort_pref ) {
							$sk    = (string) get_term_meta( $u->term_id, 'mbs_sort_key', true );
							if ( '' === $sk ) { $sk = mbs_compute_sort_key( $u->name ); }
							$first = function_exists( 'mb_strtoupper' )
								? mb_strtoupper( mb_substr( $sk, 0, 1 ) )
								: strtoupper( substr( $sk, 0, 1 ) );
						} else {
							$first = function_exists( 'mb_strtoupper' )
								? mb_strtoupper( mb_substr( $u->name, 0, 1 ) )
								: strtoupper( substr( $u->name, 0, 1 ) );
						}
						$key             = ctype_alpha( $first ) ? $first : '#';
						$grouped[ $key ][] = $u;
					}
					ksort( $grouped );
					if ( isset( $grouped['#'] ) ) {
						$hash = $grouped['#'];
						unset( $grouped['#'] );
						$grouped['#'] = $hash;
					}
				}

				if ( $updated ) :
				?>
					<div class="notice notice-success inline">
						<p><?php esc_html_e( 'Saved.', 'my-book-showroom' ); ?></p>
					</div>
				<?php endif; ?>

				<!-- Sprint RO-Display 4d-i: Global Universe Archive Display Mode -->
				<form method="post" action="" class="mbs-universe-global-form">
					<?php wp_nonce_field( 'mbs_universe_global_save', 'mbs_universe_global_nonce' ); ?>
					<div class="mbs-settings-card mbs-universe-global-display-card">
						<h3><?php esc_html_e( 'Universe Archive Display Mode', 'my-book-showroom' ); ?></h3>
						<p class="description"><?php esc_html_e( 'Controls how books are displayed on universe archive pages (can be overridden per universe below).', 'my-book-showroom' ); ?></p>
						<?php
						$_mbs_u_disp_global = get_option( 'mbs_setting_universe_archive_display_mode', 'order' );
						$_mbs_u_ro_on       = '1' === get_option( 'mbs_setting_show_universe_reading_order', '0' );
						$_mbs_u_note        = esc_html__( 'Enable Universe Reading Order in Settings -> Advanced to use these options.', 'my-book-showroom' );
						$_mbs_u_disp_opts   = array(
							'order'         => __( 'Universe Order only', 'my-book-showroom' ),
							'reading_order' => __( 'Reading Order only', 'my-book-showroom' ),
							'both'          => __( 'Both (Universe Order + Reading Order)', 'my-book-showroom' ),
						);
						?>
						<div class="mbs-display-mode-radio-group">
						<?php foreach ( $_mbs_u_disp_opts as $_mbs_udval => $_mbs_udlabel ) :
							$_mbs_u_is_dis = ( ! $_mbs_u_ro_on && 'order' !== $_mbs_udval );
						?>
						<label class="mbs-display-mode-radio<?php echo esc_attr( $_mbs_u_is_dis ? ' mbs-disabled' : '' ); ?>">
							<input type="radio"
							       name="mbs_setting_universe_archive_display_mode"
							       value="<?php echo esc_attr( $_mbs_udval ); ?>"
							       <?php checked( $_mbs_u_disp_global, $_mbs_udval ); ?>
							       <?php disabled( $_mbs_u_is_dis, true ); ?>>
							<span class="mbs-display-mode-label"><?php echo esc_html( $_mbs_udlabel ); ?></span>
							<?php if ( $_mbs_u_is_dis ) : ?><span class="description"><?php echo esc_html( $_mbs_u_note ); ?></span><?php endif; ?>
						</label>
						<?php endforeach; ?>
						</div>
						<p class="mbs-settings-actions">
							<?php submit_button( __( 'Save Display Mode', 'my-book-showroom' ), 'secondary', 'submit', false ); ?>
						</p>
					</div>
				</form>

				<?php if ( empty( $grouped ) ) : ?>
					<div class="mbs-settings-card">
						<p><?php esc_html_e( 'No universes found. Add books with universes first.', 'my-book-showroom' ); ?></p>
					</div>
				<?php else : ?>

					<div class="mbs-list-toolbar">
						<input type="search"
						       class="mbs-list-filter-input"
						       placeholder="<?php esc_attr_e( 'Filter by name…', 'my-book-showroom' ); ?>"
						       aria-label="<?php esc_attr_e( 'Filter universes', 'my-book-showroom' ); ?>">
						<p class="description mbs-list-filter-hint">
							<?php esc_html_e( 'Type to filter the list. Results update instantly.', 'my-book-showroom' ); ?>
						</p>
						<div class="mbs-sort-toggle" role="group" aria-label="<?php esc_attr_e( 'Sort order', 'my-book-showroom' ); ?>">
							<span class="mbs-sort-toggle-label"><?php esc_html_e( 'Sort by:', 'my-book-showroom' ); ?></span>
							<button type="button"
							        class="button<?php echo 'name' === $sort_pref ? ' button-primary' : ''; ?>"
							        data-sort-pref="name"
							        <?php echo 'name' === $sort_pref ? 'aria-pressed="true"' : 'aria-pressed="false"'; ?>>
								<?php esc_html_e( 'Name', 'my-book-showroom' ); ?>
							</button>
							<button type="button"
							        class="button<?php echo 'name_sort' === $sort_pref ? ' button-primary' : ''; ?>"
							        data-sort-pref="name_sort"
							        <?php echo 'name_sort' === $sort_pref ? 'aria-pressed="true"' : 'aria-pressed="false"'; ?>>
								<?php esc_html_e( 'Ignoring articles', 'my-book-showroom' ); ?>
							</button>
						</div>
						<div class="mbs-list-toolbar-actions">
							<a href="<?php echo esc_url( admin_url( 'edit-tags.php?taxonomy=' . MBS_TAX_UNIVERSE . '&post_type=' . MBS_POST_TYPE ) ); ?>" class="button">
								<?php esc_html_e( 'Add / remove universes →', 'my-book-showroom' ); ?>
							</a>
							<button type="button" class="button mbs-expand-all">
								<?php esc_html_e( 'Expand all', 'my-book-showroom' ); ?>
							</button>
							<button type="button" class="button mbs-collapse-all">
								<?php esc_html_e( 'Collapse all', 'my-book-showroom' ); ?>
							</button>
						</div>
					</div>

					<div class="mbs-universe-card-list">
						<?php foreach ( $grouped as $letter => $letter_universes ) : ?>
							<details class="mbs-letter-group" open>
								<summary class="mbs-letter-group-summary">
									<span class="mbs-letter-group-label"><?php echo esc_html( $letter ); ?></span>
									<span class="mbs-letter-group-count">
										<?php printf(
											/* translators: %d: number of universes in this letter group */
											esc_html( _n( '%d universe', '%d universes', count( $letter_universes ), 'my-book-showroom' ) ),
											count( $letter_universes )
										); ?>
									</span>
								</summary>
								<div class="mbs-letter-group-body">
									<?php foreach ( $letter_universes as $u ) :
										self::render_universe_card( $u, $saved_id );
									endforeach; ?>
								</div>
							</details>
						<?php endforeach; ?>

						<p class="mbs-filter-no-results" hidden>
							<?php esc_html_e( 'No universes match your search.', 'my-book-showroom' ); ?>
						</p>
					</div>

				<?php endif; ?>
			<?php endif; ?>

		</div>
		<?php
	}

	/**
	 * Render a single universe card via template.
	 *
	 * @param WP_Term $universe The universe term.
	 * @param int     $saved_id The term_id from the 'saved' query arg (auto-expand target).
	 * @return void
	 */
	public static function render_universe_card( WP_Term $universe, int $saved_id ): void {
		$term_id     = (int) $universe->term_id;
		$book_count  = (int) $universe->count;
		$description = (string) $universe->description;
		$is_open     = ( $term_id === $saved_id );
		$edit_url    = admin_url(
			'edit-tags.php?action=edit&taxonomy=' . MBS_TAX_UNIVERSE .
			'&tag_ID=' . $term_id . '&post_type=' . MBS_POST_TYPE
		);

		$book_ids         = MBS_Universe_Reading_Order_DAO::get_ordered_book_ids( $term_id );
		$book_display_map = MBS_Universe_Reading_Order_DAO::get_book_display_map( $book_ids );
		$has_persisted    = MBS_Universe_Reading_Order_DAO::has_persisted_order( $term_id );

		$meta_line = sprintf(
			/* translators: %d: number of books */
			_n( '%d book', '%d books', $book_count, 'my-book-showroom' ),
			$book_count
		);

		$term_layout          = (string) get_term_meta( $term_id, 'mbs_term_layout', true );
		$universe_display_mode = (string) get_term_meta( $term_id, 'mbs_universe_archive_display_mode', true );

		$banner_id  = (int) get_term_meta( $term_id, 'mbs_universe_banner_id', true );
		$banner_url = $banner_id ? (string) wp_get_attachment_image_url( $banner_id, 'medium' ) : ''; // R5-exempt: admin universes UI

		mbs_get_template_part( 'admin/universe-card', array(
			'universe'         => $universe,
			'term_id'          => $term_id,
			'book_count'       => $book_count,
			'description'      => $description,
			'is_open'          => $is_open,
			'edit_url'         => $edit_url,
			'book_ids'         => $book_ids,
			'book_display_map' => $book_display_map,
			'has_persisted'    => $has_persisted,
			'meta_line'        => $meta_line,
			'term_layout'      => $term_layout,
			'banner_id'        => $banner_id,
			'banner_url'           => $banner_url,
			'universe_display_mode' => $universe_display_mode,
		) );
	}
}
