<?php
/**
 * File Path: includes/admin/class-mbs-dashboard-widget-prefs.php
 *
 * Dashboard Widget Preferences -- DASH-2A (Spec 9d)
 *
 * Manages per-user visibility preferences for the 7 configurable dashboard
 * widgets. Storage: WP user meta `mbs_dashboard_hidden_widgets` — a
 * JSON-encoded array of widget slugs that are toggled OFF.
 * Empty array (default) means all widgets are visible.
 *
 * Always-on widgets (cannot be hidden):
 *   Catalog Stats, System Status, Onboarding Card.
 *
 * 7 configurable widgets:
 *   brand-monitor, activity-log, arc-pipeline, recently-edited,
 *   daily-quote, news-feed, whats-new.
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

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

/**
 * Class MBS_Dashboard_Widget_Prefs
 *
 * @since 1.0.0
 */
class MBS_Dashboard_Widget_Prefs {

	const META_KEY = 'mbs_dashboard_hidden_widgets';

	/**
	 * Canonical slug list for the 7 configurable widgets.
	 * Any slug not in this list is rejected by the AJAX handler.
	 *
	 * @var string[]
	 */
	const CONFIGURABLE_WIDGETS = array(
		'brand-monitor',
		'activity-log',
		'arc-pipeline',
		'recently-edited',
		'daily-quote',
		'news-feed',
		'whats-new',
	);

	/**
	 * Widget display labels for the settings panel.
	 *
	 * @var array<string, string>
	 */
	public static function get_widget_labels(): array {
		return array(
			'brand-monitor'  => __( 'Brand Monitor',   'my-book-showroom' ),
			'activity-log'   => __( 'Activity Log',    'my-book-showroom' ),
			'arc-pipeline'   => __( 'ARC Pipeline',    'my-book-showroom' ),
			'recently-edited'=> __( 'Recently Edited', 'my-book-showroom' ),
			'daily-quote'    => __( 'Daily Quote',     'my-book-showroom' ),
			'news-feed'      => __( 'MBS News Feed',   'my-book-showroom' ),
			'whats-new'      => __( 'What\'s New',     'my-book-showroom' ),
		);
	}

	/**
	 * Returns the decoded array of hidden widget slugs for a user.
	 *
	 * @param int $user_id WordPress user ID.
	 * @return string[]
	 */
	public static function get_hidden_widgets( int $user_id ): array {
		$meta = get_user_meta( $user_id, self::META_KEY, true );
		if ( empty( $meta ) ) {
			return array();
		}
		// WordPress natively unserializes user_meta arrays — no json_decode() needed.
		return is_array( $meta ) ? $meta : array();
	}

	/**
	 * Returns true if the given widget slug is hidden for the user.
	 *
	 * @param string $slug    Widget slug (must be in CONFIGURABLE_WIDGETS).
	 * @param int    $user_id WordPress user ID.
	 * @return bool
	 */
	public static function is_widget_hidden( string $slug, int $user_id ): bool {
		$hidden = self::get_hidden_widgets( $user_id );
		return in_array( $slug, $hidden, true );
	}

	/**
	 * Persists the hidden widget slugs for a user.
	 * Slugs are validated against CONFIGURABLE_WIDGETS before saving.
	 *
	 * @param int      $user_id WordPress user ID.
	 * @param string[] $slugs   Array of widget slugs to mark as hidden.
	 * @return void
	 */
	public static function save_hidden_widgets( int $user_id, array $slugs ): void {
		$valid = array_values( array_filter(
			$slugs,
			static function ( string $s ): bool {
				return in_array( $s, self::CONFIGURABLE_WIDGETS, true );
			}
		) );
		update_user_meta( $user_id, self::META_KEY, $valid );
	}

	/**
	 * Register the AJAX handler for widget preference saves.
	 *
	 * @return void
	 */
	public static function register(): void {
		add_action( 'wp_ajax_mbs_save_widget_prefs', array( static::class, 'ajax_save' ) );
	}

	/**
	 * AJAX handler: nonce-verified, sanitize slugs, persist.
	 *
	 * @return void
	 */
	public static function ajax_save(): void {
		check_ajax_referer( 'mbs_widget_prefs', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		$raw_slugs = isset( $_POST['hidden_widgets'] ) ? (array) $_POST['hidden_widgets'] : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- input sanitized via sanitize_* helpers or validated before use; see inline sanitization
		$slugs     = array_map( 'sanitize_key', $raw_slugs );

		self::save_hidden_widgets( get_current_user_id(), $slugs );
		wp_send_json_success( array( 'message' => 'Saved' ) );
	}
}
