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

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

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

	/**
	 * Render the Collections tab.
	 *
	 * Outputs the tab wrapper, the success notice (when redirected after save),
	 * and one <form>-wrapped <details> card per collection term. The card whose
	 * term_id matches the 'saved' query arg auto-expands via the 'open'
	 * attribute so the admin lands focused on the row they just edited.
	 *
	 * @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

		// F-SORT-2: Read per-user sort preference (default: name).
		$sort_pref = (string) get_user_meta( get_current_user_id(), 'mbs_sort_pref_collections', true );
		if ( ! in_array( $sort_pref, array( 'name', 'name_sort' ), true ) ) {
			$sort_pref = 'name';
		}

		$collections = get_terms( array(
			'taxonomy'   => MBS_TAX_COLLECTION,
			'hide_empty' => false,
			'orderby'    => 'name',
			'order'      => 'ASC',
		) );

		// F-SORT-2: When sort is name_sort, re-sort in PHP using mbs_sort_key.
		if ( ! is_wp_error( $collections ) && ! empty( $collections ) && 'name_sort' === $sort_pref ) {
			usort( $collections, static function ( $a, $b ) {
				$ka = (string) get_term_meta( $a->term_id, 'mbs_sort_key', true );
				$kb = (string) get_term_meta( $b->term_id, 'mbs_sort_key', true );
				if ( '' === $ka ) {
					$ka = function_exists( 'mbs_compute_sort_key' ) ? mbs_compute_sort_key( $a->name ) : strtolower( $a->name );
				}
				if ( '' === $kb ) {
					$kb = function_exists( 'mbs_compute_sort_key' ) ? mbs_compute_sort_key( $b->name ) : strtolower( $b->name );
				}
				return strcmp( $ka, $kb );
			} );
		}

		// Group collections by first letter; non-alpha names go under '#'.
		// When sort is name_sort, group by the first character of mbs_sort_key.
		$grouped = array();
		if ( ! is_wp_error( $collections ) && ! empty( $collections ) ) {
			foreach ( $collections as $c ) {
				if ( 'name_sort' === $sort_pref ) {
					$sort_key = (string) get_term_meta( $c->term_id, 'mbs_sort_key', true );
					$source   = '' !== $sort_key ? $sort_key : $c->name;
				} else {
					$source = $c->name;
				}
				$first = function_exists( 'mb_strtoupper' )
					? mb_strtoupper( mb_substr( $source, 0, 1 ) )
					: strtoupper( substr( $source, 0, 1 ) );
				$key               = ctype_alpha( $first ) ? $first : '#';
				$grouped[ $key ][] = $c;
			}
			ksort( $grouped );
			// Move '#' to the end if present.
			if ( isset( $grouped['#'] ) ) {
				$hash = $grouped['#'];
				unset( $grouped['#'] );
				$grouped['#'] = $hash;
			}
		}
		?>
		<div class="mbs-tab-collections">

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

			<h2><?php esc_html_e( 'Collections', 'my-book-showroom' ); ?><?php mbs_help_tip( __( 'A Collection groups books that share a theme, setting, or world with no required reading order. Unlike a Series, readers can start anywhere — there is no \'Book 1.\' Use Collections for standalone novels, holiday titles, or thematic sets you want readers to discover together.', 'my-book-showroom' ), __( 'What is a Collection?', '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 collection. Click a row to expand and edit.', 'my-book-showroom' ); ?>
			</p>

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

			<?php if ( empty( $grouped ) ) : ?>
				<div class="mbs-settings-card">
					<p><?php esc_html_e( 'No collections found. Add books with collections 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 collections', '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_COLLECTION . '&post_type=' . MBS_POST_TYPE ) ); ?>" class="button">
							<?php esc_html_e( 'Add / remove collections →', '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-collection-card-list">
					<?php foreach ( $grouped as $letter => $letter_collections ) : ?>
						<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 /* translators: %d: number of collections in this letter group */ printf(
										esc_html( _n( '%d collection', '%d collections', count( $letter_collections ), 'my-book-showroom' ) ),
										count( $letter_collections )
									); ?>
								</span>
							</summary>
							<div class="mbs-letter-group-body">
								<?php foreach ( $letter_collections as $c ) :
									self::render_collection_card( $c, $saved_id );
								endforeach; ?>
							</div>
						</details>
					<?php endforeach; ?>

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

			<?php endif; ?>

		</div>
		<?php
	}

	/**
	 * Render a single collection card via template.
	 *
	 * Prepares variables and delegates all HTML output to
	 * templates/admin/collection-card.php.
	 *
	 * @param WP_Term $collection The collection term.
	 * @param int     $saved_id   The term_id from the 'saved' query arg (auto-expand target).
	 * @return void
	 */
	public static function render_collection_card( WP_Term $collection, int $saved_id ): void {
		$term_id         = (int) $collection->term_id;
		$book_count      = (int) $collection->count;
		$description     = (string) $collection->description;
		$collection_type = (string) get_term_meta( $term_id, 'mbs_collection_type', true );
		$is_open         = ( $term_id === $saved_id );
		$edit_url        = admin_url(
			'edit-tags.php?action=edit&taxonomy=' . MBS_TAX_COLLECTION .
			'&tag_ID=' . $term_id . '&post_type=' . MBS_POST_TYPE
		);

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

		$meta_parts   = array();
		$meta_parts[] = sprintf(
			/* translators: %d: number of books */
			_n( '%d book', '%d books', $book_count, 'my-book-showroom' ),
			$book_count
		);
		$type_label = MBS_Taxonomy_Collection::get_type_label( $collection_type );
		if ( '' !== $type_label ) {
			$meta_parts[] = $type_label;
		}
		$meta_line = implode( ' · ', $meta_parts );

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

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

		mbs_get_template_part( 'admin/collection-card', array(
			'collection'       => $collection,
			'term_id'          => $term_id,
			'book_count'       => $book_count,
			'description'      => $description,
			'collection_type'  => $collection_type,
			'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,
		) );
	}
}
