<?php
/**
 * Settings REST API Controller
 *
 * @package Ugcify\Admin\API
 */

namespace Ugcify\Admin\API;

use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use Ugcify\Helpers\FeatureGate;

/**
 * Class SettingsAPI
 */
class SettingsAPI extends WP_REST_Controller {
	/**
	 * Namespace
	 *
	 * @var string
	 */
	protected $namespace = 'ugcify/v1';

	/**
	 * Rest base
	 *
	 * @var string
	 */
	protected $rest_base = 'settings';

	/**
	 * Option name for review form settings
	 *
	 * @var string
	 */
	private $review_form_option = 'ugcify_review_form_settings';

	/**
	 * Option name for review template settings
	 *
	 * @var string
	 */
	private $review_template_option = 'ugcify_review_template_settings';

	/**
	 * Option name for review template customization
	 *
	 * @var string
	 */
	private $template_customization_option = 'ugcify_template_customization';

	/**
	 * Option name for reels template customization settings
	 *
	 * @var string
	 */
	private $reels_settings_option = 'ugcify_reels_settings';

	/**
	 * Option name for rating tab settings
	 *
	 * @var string
	 */
	private $review_form_rating_option = 'ugcify_review_form_rating_settings';

	/**
	 * Option name for media tab settings
	 *
	 * @var string
	 */
	private $review_form_media_option = 'ugcify_review_form_media_settings';

	/**
	 * Option name for about tab settings
	 *
	 * @var string
	 */
	private $review_form_about_option = 'ugcify_review_form_about_settings';

	/**
	 * Option name for review tab settings
	 *
	 * @var string
	 */
	private $review_form_review_option = 'ugcify_review_form_review_settings';

	/**
	 * Option name for thank you tab settings
	 *
	 * @var string
	 */
	private $review_form_thank_you_option = 'ugcify_review_form_thank_you_settings';

	/**
	 * Register routes
	 */
	public function register_routes() {
		// Review form settings.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/review-form',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_review_form_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update_review_form_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
					'args'                => $this->get_review_form_settings_schema(),
				),
			)
		);

		// Review template settings.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/review-template',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_review_template_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update_review_template_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
					'args'                => $this->get_review_template_settings_schema(),
				),
			)
		);

		// Reels template customization settings.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/reels-customize',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_reels_customize_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update_reels_customize_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
			)
		);

		// Template customization settings.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/template-customize',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_template_customization' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update_template_customization' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
			)
		);
	}

	/**
	 * Check permission
	 *
	 * @return bool|WP_Error
	 */
	public function check_permission() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return new WP_Error(
				'rest_forbidden',
				__( 'Sorry, you are not allowed to access this resource.', 'ugcify' ),
				array( 'status' => 403 )
			);
		}

		return true;
	}

	/**
	 * Get review form settings
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_review_form_settings( $request ) {
		$settings = $this->get_merged_review_form_settings();

		return rest_ensure_response(
			array(
				'success' => true,
				'data'    => $settings,
			)
		);
	}

	/**
	 * Update review form settings
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function update_review_form_settings( $request ) {
		$params = $request->get_json_params();

		if ( empty( $params ) ) {
			return new WP_Error(
				'invalid_data',
				__( 'Invalid settings data.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		// Get current settings.
		$current_settings = $this->get_merged_review_form_settings();
		
		// Merge with new settings.
		$new_settings = array_merge(
			$this->get_default_review_form_settings(),
			is_array( $current_settings ) ? $current_settings : array(),
			$params
		);

		// Validate settings.
		$validation = $this->validate_review_form_settings( $new_settings );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		// Update settings.
		$updated = update_option( $this->review_form_option, $new_settings );

		if ( ! $updated && get_option( $this->review_form_option ) !== $new_settings ) {
			return new WP_Error(
				'update_failed',
				__( 'Failed to update settings.', 'ugcify' ),
				array( 'status' => 500 )
			);
		}

		$tab_update = $this->persist_tab_review_form_settings( $new_settings );
		if ( is_wp_error( $tab_update ) ) {
			return $tab_update;
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'message' => __( 'Settings updated successfully.', 'ugcify' ),
				'data'    => $new_settings,
			)
		);
	}

	/**
	 * Get default review form settings
	 *
	 * @return array
	 */
	private function get_default_review_form_settings() {
		return array(
			'formType'          => 'step-by-step',
			'formVisibility'    => 'logged-in',
			'mediaMaxSizeMb'    => 10,
			'enableAttachmentLimit' => false,
			'maxAttachmentsPerReview' => 5,
			'enableReviewFrequencyLimit' => false,
			'reviewLimitFrequencyValue' => 1,
			'reviewLimitFrequencyUnit' => 'hour',
			'maxReviewsPerFrequency' => 3,
			'maxImageSizeMb'    => 10,
			'maxVideoSizeMb'    => 50,
			'recaptchaEnabled'  => false,
			'recaptchaSiteKey'  => '',
			'recaptchaSecretKey' => '',
		);
	}

	/**
	 * Validate review form settings
	 *
	 * @param array $settings Settings to validate.
	 * @return bool|WP_Error
	 */
	private function validate_review_form_settings( $settings ) {
		$valid_form_types = array( 'step-by-step', 'single-page' );
		$valid_visibility = array( 'anyone', 'logged-in', 'verified-buyers' );

		if ( isset( $settings['formType'] ) && ! in_array( $settings['formType'], $valid_form_types, true ) ) {
			return new WP_Error(
				'invalid_form_type',
				__( 'Invalid form type. Must be "step-by-step" or "single-page".', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( isset( $settings['formVisibility'] ) && ! in_array( $settings['formVisibility'], $valid_visibility, true ) ) {
			return new WP_Error(
				'invalid_visibility',
				__( 'Invalid form visibility. Must be "anyone", "logged-in", or "verified-buyers".', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( isset( $settings['mediaMaxSizeMb'] ) ) {
			$max_media_size = (int) $settings['mediaMaxSizeMb'];
			if ( $max_media_size < 1 || $max_media_size > 2048 ) {
				return new WP_Error(
					'invalid_max_media_size',
					__( 'Invalid media max size. Value must be between 1 and 2048 MB.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		if ( isset( $settings['maxAttachmentsPerReview'] ) ) {
			$max_attachments_per_review = (int) $settings['maxAttachmentsPerReview'];
			if ( $max_attachments_per_review < 1 || $max_attachments_per_review > 100 ) {
				return new WP_Error(
					'invalid_max_attachments_per_review',
					__( 'Invalid max attachments per review. Value must be between 1 and 100.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		if ( isset( $settings['reviewLimitFrequencyValue'] ) ) {
			$review_limit_frequency_value = (int) $settings['reviewLimitFrequencyValue'];
			if ( $review_limit_frequency_value < 1 || $review_limit_frequency_value > 10000 ) {
				return new WP_Error(
					'invalid_review_limit_frequency_value',
					__( 'Invalid review frequency window value. Value must be between 1 and 10000.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		if ( isset( $settings['reviewLimitFrequencyUnit'] ) ) {
			$valid_frequency_units = array( 'minute', 'hour', 'day' );
			if ( ! in_array( $settings['reviewLimitFrequencyUnit'], $valid_frequency_units, true ) ) {
				return new WP_Error(
					'invalid_review_limit_frequency_unit',
					__( 'Invalid review frequency unit. Must be minute, hour, or day.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		if ( isset( $settings['maxReviewsPerFrequency'] ) ) {
			$max_reviews_per_frequency = (int) $settings['maxReviewsPerFrequency'];
			if ( $max_reviews_per_frequency < 1 || $max_reviews_per_frequency > 1000 ) {
				return new WP_Error(
					'invalid_max_reviews_per_frequency',
					__( 'Invalid max reviews per frequency. Value must be between 1 and 1000.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		if ( isset( $settings['maxImageSizeMb'] ) ) {
			$max_image_size = (int) $settings['maxImageSizeMb'];
			if ( $max_image_size < 1 || $max_image_size > 2048 ) {
				return new WP_Error(
					'invalid_max_image_size',
					__( 'Invalid image max size. Value must be between 1 and 2048 MB.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		if ( isset( $settings['maxVideoSizeMb'] ) ) {
			$max_video_size = (int) $settings['maxVideoSizeMb'];
			if ( $max_video_size < 1 || $max_video_size > 2048 ) {
				return new WP_Error(
					'invalid_max_video_size',
					__( 'Invalid video max size. Value must be between 1 and 2048 MB.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		return true;
	}

	/**
	 * Get review form settings schema
	 *
	 * @return array
	 */
	private function get_review_form_settings_schema() {
		return array(
			'formType'       => array(
				'type'        => 'string',
				'enum'        => array( 'step-by-step', 'single-page' ),
				'description' => __( 'The type of form to display.', 'ugcify' ),
				'required'    => false,
			),
			'formVisibility' => array(
				'type'        => 'string',
				'enum'        => array( 'anyone', 'logged-in', 'verified-buyers' ),
				'description' => __( 'Who can submit reviews.', 'ugcify' ),
				'required'    => false,
			),
			'mediaMaxSizeMb' => array(
				'type'        => 'integer',
				'description' => __( 'Maximum allowed media (image/video) size in MB.', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'absint',
			),
			'enableAttachmentLimit' => array(
				'type'        => 'boolean',
				'description' => __( 'Whether attachment count limit is enabled.', 'ugcify' ),
				'required'    => false,
			),
			'maxAttachmentsPerReview' => array(
				'type'        => 'integer',
				'description' => __( 'Maximum number of attachments allowed per review.', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'absint',
			),
			'enableReviewFrequencyLimit' => array(
				'type'        => 'boolean',
				'description' => __( 'Whether review submission frequency limit is enabled.', 'ugcify' ),
				'required'    => false,
			),
			'reviewLimitFrequencyValue' => array(
				'type'        => 'integer',
				'description' => __( 'Frequency window value for review submission limit.', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'absint',
			),
			'reviewLimitFrequencyUnit' => array(
				'type'        => 'string',
				'enum'        => array( 'minute', 'hour', 'day' ),
				'description' => __( 'Frequency window unit for review submission limit.', 'ugcify' ),
				'required'    => false,
			),
			'maxReviewsPerFrequency' => array(
				'type'        => 'integer',
				'description' => __( 'Maximum reviews allowed in the configured frequency window.', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'absint',
			),
			'maxImageSizeMb' => array(
				'type'        => 'integer',
				'description' => __( 'Maximum allowed image size in MB.', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'absint',
			),
			'maxVideoSizeMb' => array(
				'type'        => 'integer',
				'description' => __( 'Maximum allowed video size in MB.', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'absint',
			),
			'recaptchaEnabled' => array(
				'type'        => 'boolean',
				'description' => __( 'Whether reCAPTCHA is enabled for the form.', 'ugcify' ),
				'required'    => false,
			),
			'recaptchaSiteKey' => array(
				'type'        => 'string',
				'description' => __( 'Google reCAPTCHA Site Key (public key).', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'sanitize_text_field',
			),
			'recaptchaSecretKey' => array(
				'type'        => 'string',
				'description' => __( 'Google reCAPTCHA Secret Key (private key).', 'ugcify' ),
				'required'    => false,
				'sanitize_callback' => 'sanitize_text_field',
			),
		);
	}

	/**
	 * Get review template settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_review_template_settings( $request ) {
		$saved    = get_option( $this->review_template_option, array() );
		$settings = array_replace_recursive(
			$this->get_default_review_template_settings(),
			is_array( $saved ) ? $saved : array()
		);
		$settings = $this->apply_review_template_feature_gates(
			$this->sanitize_review_template_settings( $settings )
		);

		if ( is_array( $saved ) && $settings !== $saved ) {
			update_option( $this->review_template_option, $settings );
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'data'    => $settings,
			)
		);
	}

	/**
	 * Update review template settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function update_review_template_settings( $request ) {
		$params = $request->get_json_params();

		if ( empty( $params ) || ! is_array( $params ) ) {
			return new WP_Error(
				'invalid_data',
				__( 'Invalid settings data.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		$feature_validation = $this->validate_review_template_feature_access( $params );

		if ( is_wp_error( $feature_validation ) ) {
			return $feature_validation;
		}

		$current_settings = get_option( $this->review_template_option, array() );
		$current_settings = array_replace_recursive(
			$this->get_default_review_template_settings(),
			is_array( $current_settings ) ? $current_settings : array()
		);
		$current_settings = $this->apply_review_template_feature_gates(
			$this->sanitize_review_template_settings( $current_settings )
		);
		$new_settings     = array_replace_recursive(
			$this->get_default_review_template_settings(),
			$current_settings,
			$params
		);

		$new_settings = $this->apply_review_template_feature_gates(
			$this->sanitize_review_template_settings( $new_settings )
		);
		$validation   = $this->validate_review_template_settings( $new_settings, $current_settings );

		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		$updated = update_option( $this->review_template_option, $new_settings );

		if ( ! $updated && get_option( $this->review_template_option ) !== $new_settings ) {
			return new WP_Error(
				'update_failed',
				__( 'Failed to update settings.', 'ugcify' ),
				array( 'status' => 500 )
			);
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'message' => __( 'Settings updated successfully.', 'ugcify' ),
				'data'    => $new_settings,
			)
		);
	}

	/**
	 * Get default review template settings.
	 *
	 * @return array
	 */
	private function get_default_review_template_settings() {
		return array(
			'version'          => 1,
			'activeTemplateId' => '',
			'templates'        => array(
				'minimal_grid' => array(
					'enabled' => false,
				),
				'reels'        => array(
					'enabled' => false,
				),
				'gallery'      => array(
					'enabled' => false,
				),
			),
		);
	}

	/**
	 * Apply feature gates to review template settings.
	 *
	 * @param array $settings Settings.
	 * @return array
	 */
	private function apply_review_template_feature_gates( $settings ) {
		$defaults    = $this->get_default_review_template_settings();
		$allowed_ids = array_keys( $defaults['templates'] );
		$guarded     = array_replace_recursive( $defaults, is_array( $settings ) ? $settings : array() );

		if ( ! FeatureGate::is_enabled( 'block_studio_reels' ) ) {
			$guarded['templates']['reels']['enabled'] = false;
		}

		if ( ! FeatureGate::is_enabled( 'block_studio_gallery' ) ) {
			$guarded['templates']['gallery']['enabled'] = false;
		}

		$active_id = isset( $guarded['activeTemplateId'] ) ? sanitize_key( (string) $guarded['activeTemplateId'] ) : '';
		if ( 'reels' === $active_id && ! FeatureGate::is_enabled( 'block_studio_reels' ) ) {
			$active_id = '';
		}
		if ( 'gallery' === $active_id && ! FeatureGate::is_enabled( 'block_studio_gallery' ) ) {
			$active_id = '';
		}

		if ( '' !== $active_id && ! empty( $guarded['templates'][ $active_id ]['enabled'] ) ) {
			$guarded['activeTemplateId'] = $active_id;
			return $guarded;
		}

		foreach ( $allowed_ids as $template_id ) {
			if ( ! empty( $guarded['templates'][ $template_id ]['enabled'] ) ) {
				$guarded['activeTemplateId'] = $template_id;
				return $guarded;
			}
		}

		$guarded['activeTemplateId'] = '';

		return $guarded;
	}

	/**
	 * Reject locked review template settings.
	 *
	 * @param array $settings Requested settings.
	 * @return true|WP_Error
	 */
	private function validate_review_template_feature_access( $settings ) {
		if ( ! is_array( $settings ) ) {
			return true;
		}

		$requests_reels_template =
			( isset( $settings['activeTemplateId'] ) && 'reels' === sanitize_key( (string) $settings['activeTemplateId'] ) )
			|| ( isset( $settings['templates']['reels']['enabled'] ) && ! empty( $settings['templates']['reels']['enabled'] ) );

		if ( $requests_reels_template && ! FeatureGate::is_enabled( 'block_studio_reels' ) ) {
			return new WP_Error(
				'feature_locked',
				__( 'The Reels template is not available on your current plan.', 'ugcify' ),
				array( 'status' => 403 )
			);
		}

		$requests_gallery_template =
			( isset( $settings['activeTemplateId'] ) && 'gallery' === sanitize_key( (string) $settings['activeTemplateId'] ) )
			|| ( isset( $settings['templates']['gallery']['enabled'] ) && ! empty( $settings['templates']['gallery']['enabled'] ) );

		if ( $requests_gallery_template && ! FeatureGate::is_enabled( 'block_studio_gallery' ) ) {
			return new WP_Error(
				'feature_locked',
				__( 'The Attachment Carousel template is not available on your current plan.', 'ugcify' ),
				array( 'status' => 403 )
			);
		}

		return true;
	}

	/**
	 * Sanitize review template settings.
	 *
	 * @param array $settings Settings.
	 * @return array
	 */
	private function sanitize_review_template_settings( $settings ) {
		$defaults         = $this->get_default_review_template_settings();
		$allowed_ids      = array_keys( $defaults['templates'] );
		$sanitized        = $defaults;
		$requested_active = isset( $settings['activeTemplateId'] ) ? sanitize_key( $settings['activeTemplateId'] ) : '';

		if ( in_array( $requested_active, $allowed_ids, true ) || '' === $requested_active ) {
			$sanitized['activeTemplateId'] = $requested_active;
		}

		if ( isset( $settings['version'] ) ) {
			$sanitized['version'] = max( 1, (int) $settings['version'] );
		}

		if ( isset( $settings['templates'] ) && is_array( $settings['templates'] ) ) {
			foreach ( $allowed_ids as $template_id ) {
				$template = isset( $settings['templates'][ $template_id ] ) && is_array( $settings['templates'][ $template_id ] )
					? $settings['templates'][ $template_id ]
					: array();

				$sanitized['templates'][ $template_id ]['enabled'] = ! empty( $template['enabled'] );
			}
		}

		return $sanitized;
	}

	/**
	 * Get the effective active review template id.
	 *
	 * @param array $settings Settings.
	 * @return string
	 */
	private function get_effective_review_template_active_id( $settings ) {
		$defaults    = $this->get_default_review_template_settings();
		$allowed_ids = array_keys( $defaults['templates'] );
		$active_id   = isset( $settings['activeTemplateId'] ) ? sanitize_key( $settings['activeTemplateId'] ) : '';

		if ( in_array( $active_id, $allowed_ids, true ) ) {
			return $active_id;
		}

		foreach ( $allowed_ids as $template_id ) {
			if ( ! empty( $settings['templates'][ $template_id ]['enabled'] ) ) {
				return $template_id;
			}
		}

		return '';
	}

	/**
	 * Validate review template settings.
	 *
	 * @param array $settings Settings.
	 * @param array $current_settings Current settings.
	 * @return bool|WP_Error
	 */
	private function validate_review_template_settings( $settings, $current_settings = array() ) {
		$defaults    = $this->get_default_review_template_settings();
		$allowed_ids = array_keys( $defaults['templates'] );
		$active_id   = isset( $settings['activeTemplateId'] ) ? $settings['activeTemplateId'] : '';
		$current_id  = $this->get_effective_review_template_active_id( $current_settings );
		$enabled_ids = array();

		foreach ( $allowed_ids as $template_id ) {
			if ( ! empty( $settings['templates'][ $template_id ]['enabled'] ) ) {
				$enabled_ids[] = $template_id;
			}
		}

		if ( '' !== $active_id && ! in_array( $active_id, $allowed_ids, true ) ) {
			return new WP_Error(
				'invalid_active_template',
				__( 'Invalid active template id.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( count( $enabled_ids ) > 1 ) {
			return new WP_Error(
				'multiple_active_templates',
				__( 'Only one review template can be enabled at a time.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( '' === $active_id && ! empty( $enabled_ids ) ) {
			return new WP_Error(
				'missing_active_template',
				__( 'An enabled template must also be marked as active.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( '' !== $current_id && '' === $active_id ) {
			return new WP_Error(
				'active_template_required',
				__( 'The enabled template cannot be disabled directly. Enable another template instead.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( '' !== $active_id ) {
			$is_enabled = ! empty( $settings['templates'][ $active_id ]['enabled'] );

			if ( ! $is_enabled ) {
				return new WP_Error(
					'inactive_template_selected',
					__( 'Active template must be enabled.', 'ugcify' ),
					array( 'status' => 400 )
				);
			}
		}

		return true;
	}

	/**
	 * Get review template settings schema.
	 *
	 * @return array
	 */
	private function get_review_template_settings_schema() {
		return array(
			'version'          => array(
				'type'        => 'integer',
				'description' => __( 'Settings schema version.', 'ugcify' ),
				'required'    => false,
			),
			'activeTemplateId' => array(
				'type'        => 'string',
				'description' => __( 'Current active review template id.', 'ugcify' ),
				'required'    => false,
			),
			'templates'        => array(
				'type'        => 'object',
				'description' => __( 'Review template settings map.', 'ugcify' ),
				'required'    => false,
			),
		);
	}

	/**
	 * Get template customization settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_template_customization( $request ) {
		$saved           = get_option( $this->template_customization_option, array() );
		$stored_settings = is_array( $saved ) ? $saved : array();

		if ( isset( $stored_settings['tagStyle'] ) ) {
			unset( $stored_settings['tagStyle'] );
		}

		$settings = array_merge( $this->get_default_template_customization(), $stored_settings );
		$settings = $this->apply_template_customization_feature_gates(
			$this->sanitize_template_customization( $settings )
		);

		if ( is_array( $saved ) && $settings !== $stored_settings ) {
			update_option( $this->template_customization_option, $settings );
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'data'    => $settings,
			)
		);
	}

	/**
	 * Update template customization settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function update_template_customization( $request ) {
		$params = $request->get_json_params();

		if ( empty( $params ) || ! is_array( $params ) ) {
			return new WP_Error(
				'invalid_data',
				__( 'Invalid settings data.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		$feature_validation = $this->validate_template_customization_feature_access( $params );

		if ( is_wp_error( $feature_validation ) ) {
			return $feature_validation;
		}

		$current_settings = get_option( $this->template_customization_option, array() );

		if ( is_array( $current_settings ) && isset( $current_settings['tagStyle'] ) ) {
			unset( $current_settings['tagStyle'] );
		}

		$current_settings = $this->apply_template_customization_feature_gates(
			$this->sanitize_template_customization(
				array_merge(
					$this->get_default_template_customization(),
					is_array( $current_settings ) ? $current_settings : array()
				)
			)
		);
		$new_settings     = array_merge(
			$this->get_default_template_customization(),
			$current_settings,
			$params
		);

		$new_settings = $this->apply_template_customization_feature_gates(
			$this->sanitize_template_customization( $new_settings )
		);

		// Validate slider widget constraints
		$validation_error = $this->validate_slider_constraints( $new_settings );
		if ( is_wp_error( $validation_error ) ) {
			return $validation_error;
		}

		$updated = update_option( $this->template_customization_option, $new_settings );

		if ( ! $updated && get_option( $this->template_customization_option ) !== $new_settings ) {
			return new WP_Error(
				'update_failed',
				__( 'Failed to update settings.', 'ugcify' ),
				array( 'status' => 500 )
			);
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'message' => __( 'Template customization saved successfully.', 'ugcify' ),
				'data'    => $new_settings,
			)
		);
	}

	/**
	 * Get default template customization settings.
	 *
	 * @return array
	 */
	private function get_default_template_customization() {
		return array(
			// General.
			'enableWidget'            => true,
			'widgetType'              => 'grid',

			// Header Area.
			'showHeaderTitle'         => true,
			'title'                   => 'Customers are saying',
			'titleFontWeight'         => '600',
			'titleFontSize'           => 'medium',
			'emptyReviewText'         => 'No customer review yet.',
			'showMediaCarousel'       => true,
			'mediaCarouselItemsToShow' => '10',

			// Colors and Styles.
			'primaryColor'            => '#201CFE',
			'titleColor'              => '#000000',
			'bodyFontColor'           => '#444444',
			'cardBgColor'             => '#FFFFFF',
			'ratingColor'             => '#FFA800',
			'buttonTextColor'         => '#FFFFFF',
			'filterFillColor'         => '#FFFFFF',
			'filterStrokeColor'       => '#201CFE',
			'filterIconColor'         => '#292D32',
			'readMoreColor'           => '#000000',
			'loadMoreTextColor'       => '#201CFE',
			'loadMoreBgColor'         => '#FFFFFF',
			'loadMoreBorderColor'     => '#201CFE',

			// Review Section.
			'reviewerNameFormat'      => 'full',
			'reviewerNameFontSize'    => 'medium',
			'showVerifiedCheck'       => true,
			'showInfluencerBadge'     => true,
			'reviewDateFormat'        => 'd M, Y',
			'starRatingSize'          => 'medium',
			'reviewTextSize'          => 'medium',
			'reviewTextLength'        => 'large',
			'showReviews'             => true,
			'reviewCardBorderRadius'  => '10',
			'reviewColumn'            => '3',
			'reviewsPerPage'          => '3',
			'showLoadMoreButton'      => true,
			'loadMoreTextSize'        => 'medium',
			'loadMoreBorderRadius'    => '10',
			'paginationType'          => 'page_number',

			// Advanced.
			'customCSS'               => '',
			'shortcode'               => '[ugcify_reviews product_id="123"]',

			// Layout & Grid.
			'gridStyle'               => 'masonry',
			'columnsDesktop'          => '3',
			'gapSpacing'              => '16',

			// Media Behavior.
			'lazyLoadImages'          => true,
			'autoplayVideo'           => false,
			'enableLightbox'          => true,

			// Shoppable Tags.
			'directAddToCart'         => true,

			// Interactions.
			'enableUpvotes'           => false,
			'socialShareButtons'      => false,
			'customersAlsoBought'     => false,
		);
	}

	/**
	 * Get premium-only template customization fields grouped by feature gate.
	 *
	 * @return array
	 */
	private function get_template_customization_locked_fields() {
		return array(
			'block_studio_advanced' => array(
				'primaryColor',
				'titleColor',
				'bodyFontColor',
				'cardBgColor',
				'ratingColor',
				'buttonTextColor',
				'filterFillColor',
				'filterStrokeColor',
				'filterIconColor',
				'readMoreColor',
				'loadMoreTextColor',
				'loadMoreBgColor',
				'loadMoreBorderColor',
				'lazyLoadImages',
				'autoplayVideo',
				'enableLightbox',
				'customCSS',
			),
		);
	}

	/**
	 * Get template customization fields that are unavailable in the free build.
	 *
	 * @return array
	 */
	private function get_template_customization_disabled_fields() {
		return array(
			'enableUpvotes',
			'socialShareButtons',
			'customersAlsoBought',
		);
	}

	/**
	 * Normalize template customization settings for the active feature set.
	 *
	 * @param array $settings Settings.
	 * @return array
	 */
	private function apply_template_customization_feature_gates( $settings ) {
		$defaults = $this->get_default_template_customization();
		$guarded  = array_merge( $defaults, is_array( $settings ) ? $settings : array() );

		foreach ( $this->get_template_customization_locked_fields() as $feature => $fields ) {
			if ( FeatureGate::is_enabled( $feature ) ) {
				continue;
			}

			foreach ( $fields as $field ) {
				$guarded[ $field ] = $defaults[ $field ];
			}
		}

		foreach ( $this->get_template_customization_disabled_fields() as $field ) {
			$guarded[ $field ] = $defaults[ $field ];
		}

		return $guarded;
	}

	/**
	 * Reject locked template customization settings from direct requests.
	 *
	 * @param array $settings Requested settings.
	 * @return true|WP_Error
	 */
	private function validate_template_customization_feature_access( $settings ) {
		if ( ! is_array( $settings ) ) {
			return true;
		}

		$defaults  = $this->get_default_template_customization();
		$requested = $this->sanitize_template_customization( array_merge( $defaults, $settings ) );

		foreach ( $this->get_template_customization_locked_fields() as $feature => $fields ) {
			if ( FeatureGate::is_enabled( $feature ) ) {
				continue;
			}

			foreach ( $fields as $field ) {
				if ( array_key_exists( $field, $settings ) && $requested[ $field ] !== $defaults[ $field ] ) {
					return new WP_Error(
						'feature_locked',
						__( 'Premium template customization settings are not available on your current plan.', 'ugcify' ),
						array( 'status' => 403 )
					);
				}
			}
		}

		foreach ( $this->get_template_customization_disabled_fields() as $field ) {
			if ( array_key_exists( $field, $settings ) && $requested[ $field ] !== $defaults[ $field ] ) {
				return new WP_Error(
					'feature_unavailable',
					__( 'Interaction settings are not available in this build.', 'ugcify' ),
					array( 'status' => 403 )
				);
			}
		}

		return true;
	}

	/**
	 * Sanitize template customization settings.
	 *
	 * @param array $settings Settings.
	 * @return array
	 */
	private function sanitize_template_customization( $settings ) {
		$sanitized = array();

		// Boolean fields.
		$boolean_fields = array(
			'enableWidget',
			'showHeaderTitle',
			'showVerifiedCheck',
			'showInfluencerBadge',
			'showReviews',
			'showMediaCarousel',
			'lazyLoadImages',
			'autoplayVideo',
			'enableLightbox',
			'directAddToCart',
			'enableUpvotes',
			'socialShareButtons',
			'customersAlsoBought',
			'showLoadMoreButton',
		);
		foreach ( $boolean_fields as $field ) {
			if ( isset( $settings[ $field ] ) ) {
				$sanitized[ $field ] = (bool) $settings[ $field ];
			}
		}

		// String fields.
		$string_fields = array(
			'title',
			'titleFontWeight',
			'titleFontSize',
			'emptyReviewText',
			'reviewerNameFormat',
			'reviewerNameFontSize',
			'reviewDateFormat',
			'starRatingSize',
			'reviewTextSize',
			'reviewTextLength',
			'mediaCarouselItemsToShow',
			'reviewColumn',
			'reviewsPerPage',
			'loadMoreTextSize',
			'loadMoreBorderRadius',
			'paginationType',
			'customCSS',
			'shortcode',
			'gridStyle',
			'columnsDesktop',
			'gapSpacing',
		);
		foreach ( $string_fields as $field ) {
			if ( isset( $settings[ $field ] ) ) {
				$sanitized[ $field ] = sanitize_text_field( $settings[ $field ] );
			}
		}

		if ( isset( $settings['widgetType'] ) ) {
			$widget_type = sanitize_key( (string) $settings['widgetType'] );
			if ( in_array( $widget_type, array( 'grid', 'masonry', 'slider', 'list', 'reels', 'gallery' ), true ) ) {
				$sanitized['widgetType'] = $widget_type;
			}
		}

		// Color fields (with validation).
		$color_fields = array(
			'primaryColor',
			'titleColor',
			'bodyFontColor',
			'cardBgColor',
			'ratingColor',
			'buttonTextColor',
			'filterFillColor',
			'filterStrokeColor',
			'filterIconColor',
			'readMoreColor',
			'loadMoreTextColor',
			'loadMoreBgColor',
			'loadMoreBorderColor',
		);
		foreach ( $color_fields as $field ) {
			if ( isset( $settings[ $field ] ) ) {
				$color = sanitize_text_field( $settings[ $field ] );
				// Basic hex color validation.
				if ( preg_match( '/^#[a-f0-9]{6}$/i', $color ) ) {
					$sanitized[ $field ] = $color;
				}
			}
		}

		// Numeric string with unit (border radius).
		if ( isset( $settings['reviewCardBorderRadius'] ) ) {
			$sanitized['reviewCardBorderRadius'] = sanitize_text_field( $settings['reviewCardBorderRadius'] );
		}

		if ( isset( $sanitized['widgetType'] ) ) {
			if ( 'grid' === $sanitized['widgetType'] ) {
				$sanitized['gridStyle'] = 'uniform_grid';
			} elseif ( 'masonry' === $sanitized['widgetType'] ) {
				$sanitized['gridStyle'] = 'masonry';
			}
		}

		return $sanitized;
	}

	/**
	 * Validate slider widget constraints.
	 *
	 * For slider widget type, reviews per page cannot exceed review column count.
	 *
	 * @param array $settings Settings to validate.
	 * @return true|WP_Error True if valid, WP_Error otherwise.
	 */
	private function validate_slider_constraints( $settings ) {
		if ( ! isset( $settings['widgetType'] ) || 'slider' !== $settings['widgetType'] ) {
			return true;
		}

		$reviews_per_page = isset( $settings['reviewsPerPage'] ) ? (int) $settings['reviewsPerPage'] : 3;
		$review_column    = isset( $settings['reviewColumn'] ) ? (int) $settings['reviewColumn'] : 3;

		if ( $reviews_per_page > $review_column ) {
			return new WP_Error(
				'invalid_slider_settings',
				sprintf(
					/* translators: %d: number of columns */
					__( 'For Slider widget, reviews per page cannot exceed %d (the number of columns).', 'ugcify' ),
					$review_column
				),
				array( 'status' => 400 )
			);
		}

		return true;
	}

	/**
	 * Get option map for review form tabs
	 *
	 * @return array
	 */
	private function get_review_form_tab_option_map() {
		return array(
			'rating'    => $this->review_form_rating_option,
			'media'     => $this->review_form_media_option,
			'about'     => $this->review_form_about_option,
			'review'    => $this->review_form_review_option,
			'thank_you' => $this->review_form_thank_you_option,
		);
	}

	/**
	 * Get merged review form settings from legacy + tab options.
	 *
	 * @return array
	 */
	private function get_merged_review_form_settings() {
		$settings = $this->get_default_review_form_settings();
		$saved    = get_option( $this->review_form_option, array() );

		if ( is_array( $saved ) && ! empty( $saved ) ) {
			$settings = array_merge( $settings, $saved );
		}

		foreach ( $this->get_review_form_tab_option_map() as $option_name ) {
			$tab_settings = get_option( $option_name, array() );
			if ( is_array( $tab_settings ) && ! empty( $tab_settings ) ) {
				$settings = array_merge( $settings, $tab_settings );
			}
		}

		return $settings;
	}

	/**
	 * Persist tab specific review form settings in dedicated options.
	 *
	 * @param array $settings Full review form settings.
	 * @return true|WP_Error
	 */
	private function persist_tab_review_form_settings( $settings ) {
		foreach ( $this->get_review_form_tab_option_map() as $tab_key => $option_name ) {
			$tab_settings = $this->extract_review_form_settings_group( $settings, $tab_key );
			$updated      = update_option( $option_name, $tab_settings );

			if ( ! $updated && get_option( $option_name ) !== $tab_settings ) {
				return new WP_Error(
					'update_failed',
					sprintf(
						/* translators: %s is review form tab option key. */
						__( 'Failed to update %s settings.', 'ugcify' ),
						$tab_key
					),
					array( 'status' => 500 )
				);
			}
		}

		return true;
	}

	/**
	 * Extract settings for a specific review form tab group.
	 *
	 * @param array  $settings Full review form settings.
	 * @param string $group_key Target group key.
	 * @return array
	 */
	private function extract_review_form_settings_group( $settings, $group_key ) {
		if ( ! is_array( $settings ) ) {
			return array();
		}

		$group_settings = array();
		foreach ( $settings as $setting_key => $setting_value ) {
			if ( $group_key === $this->get_review_form_settings_group_key( $setting_key ) ) {
				$group_settings[ $setting_key ] = $setting_value;
			}
		}

		return $group_settings;
	}

	/**
	 * Resolve review form setting group key by setting name.
	 *
	 * @param string $setting_key Setting key.
	 * @return string
	 */
	private function get_review_form_settings_group_key( $setting_key ) {
		$setting_key = (string) $setting_key;

		if ( 'showRatingTitle' === $setting_key || 0 === strpos( $setting_key, 'rating' ) ) {
			return 'rating';
		}

		if ( 'showMediaTitle' === $setting_key || 0 === strpos( $setting_key, 'media' ) ) {
			return 'media';
		}

		if ( 'showAboutTitle' === $setting_key || 0 === strpos( $setting_key, 'about' ) ) {
			return 'about';
		}

		if ( 'showReviewTitle' === $setting_key || 0 === strpos( $setting_key, 'review' ) ) {
			return 'review';
		}

		if ( 0 === strpos( $setting_key, 'thankYou' ) || 0 === strpos( $setting_key, 'showThankYou' ) ) {
			return 'thank_you';
		}

		return 'general';
	}

	// ── Reels Template Customization ─────────────────────────────────────────

	/**
	 * Get reels template customization settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_reels_customize_settings( $request ) {
		if ( ! FeatureGate::is_enabled( 'block_studio_reels' ) ) {
			return new WP_Error(
				'feature_locked',
				__( 'The Reels template is not available on your current plan.', 'ugcify' ),
				array( 'status' => 403 )
			);
		}

		$defaults = $this->get_default_reels_settings();
		$saved    = get_option( $this->reels_settings_option, array() );

		if ( is_array( $saved ) && ! empty( $saved ) ) {
			$settings = array_merge( $defaults, $saved );
		} else {
			$settings = $defaults;
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'data'    => $settings,
			)
		);
	}

	/**
	 * Update reels template customization settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function update_reels_customize_settings( $request ) {
		if ( ! FeatureGate::is_enabled( 'block_studio_reels' ) ) {
			return new WP_Error(
				'feature_locked',
				__( 'The Reels template is not available on your current plan.', 'ugcify' ),
				array( 'status' => 403 )
			);
		}

		$params = $request->get_json_params();

		if ( empty( $params ) || ! is_array( $params ) ) {
			return new WP_Error(
				'invalid_data',
				__( 'Invalid settings data.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		$current  = get_option( $this->reels_settings_option, array() );
		$merged   = array_merge(
			$this->get_default_reels_settings(),
			is_array( $current ) ? $current : array(),
			$params
		);
		$new_settings = $this->sanitize_reels_settings( $merged );

		update_option( $this->reels_settings_option, $new_settings );

		return rest_ensure_response(
			array(
				'success' => true,
				'message' => __( 'Reels settings saved successfully.', 'ugcify' ),
				'data'    => $new_settings,
			)
		);
	}

	/**
	 * Get default reels template settings.
	 *
	 * @return array
	 */
	private function get_default_reels_settings() {
		return array(
			// Customer Stories section.
			'showStories'       => true,
			'storiesTitle'      => 'Customer Stories',
			'storiesMaxCount'   => 8,
			'showAddYours'      => true,

			// Community Reviews section.
			'showCommunity'     => true,
			'communityTitle'    => 'Community Reviews',
			'communitySubtitle' => 'See what our customers are saying',
			'showShareBtn'      => true,

			// Review display (shared with template_customization, overridden for reels).
			'reviewerNameFormat' => 'first_last_initial',
			'reviewDateFormat'   => 'd M, Y',
			'showVerifiedCheck'  => true,
			'reviewsPerPage'     => '12',

			// Colors.
			'primaryColor' => '#201CFE',
			'ratingColor'  => '#FFA800',

			// Advanced.
			'customCSS' => '',

			// Media Behavior.
			'lazyLoadImages'     => true,
			'autoplayVideo'      => false,
			'enableLightbox'     => true,

			// Shoppable Tags.
			'tagStyle'           => 'pulsing_dot',
			'directAddToCart'    => true,
			'slideInAfterSeconds' => 3,

			// Interactions.
			'enableUpvotes'      => false,
			'socialShareButtons' => false,
			'customersAlsoBought' => false,
		);
	}

	/**
	 * Sanitize reels template settings.
	 *
	 * @param array $settings Settings array.
	 * @return array
	 */
	private function sanitize_reels_settings( $settings ) {
		$defaults  = $this->get_default_reels_settings();
		$sanitized = $defaults;

		// Boolean fields.
		foreach ( array( 'showStories', 'showAddYours', 'showCommunity', 'showShareBtn', 'showVerifiedCheck', 'lazyLoadImages', 'autoplayVideo', 'enableLightbox', 'directAddToCart', 'enableUpvotes', 'socialShareButtons', 'customersAlsoBought' ) as $bool_key ) {
			if ( array_key_exists( $bool_key, $settings ) ) {
				$sanitized[ $bool_key ] = (bool) $settings[ $bool_key ];
			}
		}

		// Text fields.
		foreach ( array( 'storiesTitle', 'communityTitle', 'communitySubtitle' ) as $text_key ) {
			if ( isset( $settings[ $text_key ] ) ) {
				$sanitized[ $text_key ] = sanitize_text_field( (string) $settings[ $text_key ] );
			}
		}

		// Bounded integer.
		if ( isset( $settings['storiesMaxCount'] ) ) {
			$sanitized['storiesMaxCount'] = max( 1, min( 20, intval( $settings['storiesMaxCount'] ) ) );
		}

		if ( isset( $settings['reviewsPerPage'] ) ) {
			$sanitized['reviewsPerPage'] = (string) max( 1, min( 100, intval( $settings['reviewsPerPage'] ) ) );
		}

		if ( isset( $settings['slideInAfterSeconds'] ) ) {
			$sanitized['slideInAfterSeconds'] = max( 0, intval( $settings['slideInAfterSeconds'] ) );
		}

		// Enum fields.
		$allowed_name_formats = array( 'full', 'first_last_initial', 'first_only', 'initials' );
		if ( isset( $settings['reviewerNameFormat'] ) && in_array( $settings['reviewerNameFormat'], $allowed_name_formats, true ) ) {
			$sanitized['reviewerNameFormat'] = $settings['reviewerNameFormat'];
		}

		$allowed_date_formats = array( 'd M, Y', 'M d, Y', 'd/m/Y', 'Y-m-d' );
		if ( isset( $settings['reviewDateFormat'] ) && in_array( $settings['reviewDateFormat'], $allowed_date_formats, true ) ) {
			$sanitized['reviewDateFormat'] = $settings['reviewDateFormat'];
		}

		// Colors.
		foreach ( array( 'primaryColor', 'ratingColor' ) as $color_key ) {
			if ( isset( $settings[ $color_key ] ) && preg_match( '/^#[0-9a-fA-F]{6}$/', $settings[ $color_key ] ) ) {
				$sanitized[ $color_key ] = $settings[ $color_key ];
			}
		}

		// Tag style enum.
		$allowed_tag_styles = array( 'pulsing_dot', 'simple_badge', 'none' );
		if ( isset( $settings['tagStyle'] ) && in_array( $settings['tagStyle'], $allowed_tag_styles, true ) ) {
			$sanitized['tagStyle'] = $settings['tagStyle'];
		}

		// Custom CSS.
		if ( isset( $settings['customCSS'] ) ) {
			$sanitized['customCSS'] = sanitize_textarea_field( (string) $settings['customCSS'] );
		}

		return $sanitized;
	}
}
