<?php
/**
 * File Path: includes/data/class-mbs-brand-feed-url-dao.php
 *
 * Brand Feed URL DAO
 *
 * Replaces the mbs_setting_brand_feed_urls wp_options JSON blob (RF-012).
 * Table created by MBS_DB_Schema::brand_feed_urls() / MBS_Migration_4_24.
 *
 * @package MyBookShowroom
 * @since   1.3.0
 */

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

/**
 * Class MBS_Brand_Feed_URL_DAO
 *
 * @since 1.3.0
 */
// 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_Brand_Feed_URL_DAO { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	// ── Write operations ────────────────────────────────────────────────────

	/**
	 * Replace all stored feed URLs with the provided list.
	 *
	 * Deletes all existing rows then inserts each URL from $urls,
	 * preserving the input array order as sort_order.
	 * Empty strings and non-URL values are silently skipped.
	 * Duplicate URLs are skipped via the UNIQUE KEY constraint (INSERT IGNORE).
	 *
	 * @param  string[] $urls Array of validated feed URL strings.
	 * @return void
	 * @since  1.3.0
	 */
	public static function save_all( array $urls ): void {
		global $wpdb;
		$table = $wpdb->prefix . 'mbs_brand_feed_urls';
		$now   = current_time( 'mysql', true ); // UTC (A-005).

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$wpdb->query( "DELETE FROM `{$table}`" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery -- DAO layer -- direct DB access is intentional per MBS architecture

		foreach ( $urls as $i => $url ) {
			$url = esc_url_raw( (string) $url );
			if ( '' === $url ) {
				continue;
			}
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
			$wpdb->insert(
				$table,
				array(
					'feed_url'   => $url,
					'sort_order' => $i,
					'created_at' => $now,
					'updated_at' => $now,
				),
				array( '%s', '%d', '%s', '%s' )
			);
		}
	}

	// ── Read operations ─────────────────────────────────────────────────────

	/**
	 * Return all feed URLs as a plain array of strings, ordered by sort_order.
	 *
	 * @return string[]
	 * @since  1.3.0
	 */
	public static function get_all(): array {
		global $wpdb;
		$table = $wpdb->prefix . 'mbs_brand_feed_urls';

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$rows = $wpdb->get_col( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery -- DAO layer -- direct DB access is intentional per MBS architecture
			"SELECT feed_url FROM `{$table}` ORDER BY sort_order ASC"
		);

		return is_array( $rows ) ? $rows : array();
	}
}
