<?php
/**
 * Sanitize widget_settings JSON from AJAX: nonce proves origin, not payload integrity.
 *
 * @package UM_Elementor_Free
 * @since   2.7
 */

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

final class UM_Elementor_Ajax_Widget_Settings {

	/**
	 * Keys allowed to influence UM_User_Query_Engine / list queries from client JSON.
	 *
	 * @var string[]
	 */
	private const QUERY_ENGINE_KEYS = [
		'enable_pagination',
		'users_per_page',
		'user_numbers',
		'pagination_style',
		'query_show_selected_roles',
		'query_user_roles',
		'roles',
		'query_user_order_by',
		'query_user_order',
		'orderby',
		'order',
		'show_only_approved_users',
		'user_query_by_meta_key',
		'um_elementor_user_meta_fields',
		'user_meta_fields',
	];

	/**
	 * Extra keys stored in WP User List default widget settings (display only; still allowlist).
	 *
	 * @var string[]
	 */
	private const WP_WIDGET_UI_KEYS = [
		'um_elementor_show_user_image',
		'um_elementor_show_member_name',
		'um_elementor_show_user_meta',
		'title_alignment',
		'user_layout',
	];

	/**
	 * @param array<string, mixed> $decoded
	 * @return array<string, mixed>
	 */
	public static function sanitize_for_query_engine( array $decoded ): array {
		$slice = array_intersect_key( $decoded, array_flip( self::QUERY_ENGINE_KEYS ) );

		if ( isset( $slice['um_elementor_user_meta_fields'] ) ) {
			$slice['um_elementor_user_meta_fields'] = array_values(
				array_filter( array_map( 'sanitize_key', (array) $slice['um_elementor_user_meta_fields'] ) )
			);
		}
		if ( isset( $slice['user_meta_fields'] ) ) {
			$from_repeater = array_values(
				array_filter( array_map( 'sanitize_key', (array) $slice['user_meta_fields'] ) )
			);
			if ( empty( $slice['um_elementor_user_meta_fields'] ) ) {
				$slice['um_elementor_user_meta_fields'] = $from_repeater;
			}
			unset( $slice['user_meta_fields'] );
		}

		if ( ! empty( $slice['query_user_roles'] ) && is_array( $slice['query_user_roles'] ) ) {
			$slice['roles'] = array_map( 'sanitize_text_field', $slice['query_user_roles'] );
		}
		unset( $slice['query_user_roles'] );

		if ( ! empty( $slice['roles'] ) && is_array( $slice['roles'] ) ) {
			$slice['roles'] = array_map( 'sanitize_text_field', $slice['roles'] );
		}

		if ( isset( $slice['user_query_by_meta_key'] ) ) {
			$slice['user_query_by_meta_key'] = sanitize_key( (string) $slice['user_query_by_meta_key'] );
		}

		if ( isset( $slice['query_user_order'] ) ) {
			$o                         = strtoupper( (string) $slice['query_user_order'] );
			$slice['query_user_order'] = ( 'DESC' === $o ) ? 'DESC' : 'ASC';
			$slice['order']            = $slice['query_user_order'];
		} elseif ( isset( $slice['order'] ) ) {
			$o              = strtoupper( (string) $slice['order'] );
			$slice['order'] = ( 'DESC' === $o ) ? 'DESC' : 'ASC';
		}

		if ( ! empty( $slice['query_user_order_by'] ) && empty( $slice['orderby'] ) ) {
			$map = [
				'ID'              => 'id',
				'display_name'    => 'display_name',
				'user_name'       => 'login',
				'user_email'      => 'email',
				'user_registered' => 'registered',
				'post_count'      => 'post_count',
				'first_name'      => 'first_name',
				'last_name'       => 'last_name',
				'custom_field'    => 'custom_field',
				'last_login'      => 'last_login',
			];
			$k                = $slice['query_user_order_by'];
			$slice['orderby'] = isset( $map[ $k ] ) ? $map[ $k ] : 'registered';
		}

		return $slice;
	}

	/**
	 * @return array<string, mixed>
	 */
	public static function from_post_um_list(): array {
		$raw = json_decode( wp_unslash( $_POST['widget_settings'] ?? '' ), true );
		if ( ! is_array( $raw ) ) {
			return [];
		}

		return self::sanitize_for_query_engine( $raw );
	}

	/**
	 * Trusted slice for WP User List: query keys + UI defaults merge.
	 *
	 * @param array<string, mixed> $defaults
	 * @return array<string, mixed>
	 */
	public static function from_post_wp_list( array $defaults ): array {
		if ( empty( $_POST['widget_settings'] ) ) {
			return $defaults;
		}
		$raw = json_decode( wp_unslash( $_POST['widget_settings'] ), true );
		if ( ! is_array( $raw ) ) {
			return $defaults;
		}
		$allowed     = array_merge( self::QUERY_ENGINE_KEYS, self::WP_WIDGET_UI_KEYS );
		$trusted     = array_intersect_key( $raw, array_flip( $allowed ) );
		$query_slice = self::sanitize_for_query_engine( $trusted );
		$ui_slice    = array_intersect_key( $trusted, array_flip( self::WP_WIDGET_UI_KEYS ) );

		return wp_parse_args( array_merge( $ui_slice, $query_slice ), $defaults );
	}
}
