<?php
/**
 * File Path: includes/data/class-mbs-taxonomy-count-dao.php
 *
 * MBS Taxonomy Count DAO
 *
 * Counts non-trashed, non-auto-draft mbs_book posts per term.
 * This is the RF-013 fix: WP core only counts published posts, but
 * MBS counts all active editing statuses so term counts stay accurate
 * for authors with draft-only books.
 *
 * @package MyBookShowroom
 * @since   1.3.5
 */

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

// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- DAO/migration: table names via $wpdb->prefix are trusted server-controlled values, not user input
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter -- same reason: $wpdb->prefix table names are safe; $where_sql is built from sanitized server-controlled inputs
class MBS_Taxonomy_Count_DAO { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	/**
	 * Update the book count for a given term_taxonomy_id.
	 *
	 * Counts all mbs_book posts in non-trashed, non-auto-draft statuses.
	 * Called as a WP update_count_callback registered in register_taxonomy().
	 *
	 * @param int $ttid  term_taxonomy_id to update.
	 * @return void
	 */
	public static function update_term_book_count( int $ttid ): void {
		global $wpdb;

		$post_statuses = array_diff( get_post_stati(), array( 'trash', 'auto-draft' ) );
		$statuses_in   = implode( ',', array_fill( 0, count( $post_statuses ), '%s' ) );

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- safe: variadic ...$params / ...$row_ids correctly matches prepared placeholders; PHPCS cannot statically verify spread arg count
		$count = (int) $wpdb->get_var(
			$wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- safe: variadic ...$params spread correctly matches prepared placeholders; PHPCS cannot statically verify spread arg count
				"SELECT COUNT(*) FROM {$wpdb->posts} p
				 INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
				 WHERE tr.term_taxonomy_id = %d
				 AND p.post_status IN ( $statuses_in )
				 AND p.post_type = %s",
				array_merge( array( $ttid ), $post_statuses, array( MBS_POST_TYPE ) )
			)
		);

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
		$wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery -- DAO layer -- direct DB access is intentional per MBS architecture
			$wpdb->term_taxonomy,
			array( 'count' => $count ),
			array( 'term_taxonomy_id' => $ttid )
		);
	}
}
