<?php
/**
 * Settings AJAX handlers — option / preference persistence.
 *
 * @package CoffeeWP_Media_Cleanup
 */

namespace CWPM\Ajax;

use CWPM\Thumbnail\Sizes;

defined( 'ABSPATH' ) || exit;

// phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce verified centrally in BaseHandler::verify_request().

class SettingsHandler extends BaseHandler {

	/**
	 * Constructor — register AJAX actions.
	 */
	public function __construct() {
		add_action( 'wp_ajax_cwpm_save_theme', array( $this, 'save_theme' ) );
		add_action( 'wp_ajax_cwpm_save_batch_size', array( $this, 'save_batch_size' ) );
		add_action( 'wp_ajax_cwpm_get_settings', array( $this, 'get_settings' ) );
		add_action( 'wp_ajax_cwpm_save_user_prefs', array( $this, 'save_user_prefs' ) );
		add_action( 'wp_ajax_cwpm_save_trash_settings', array( $this, 'save_trash_settings' ) );
		add_action( 'wp_ajax_cwpm_prescan_option_save', array( $this, 'prescan_option_save' ) );
	}

	/**
	 * Save the user's theme preference via AJAX.
	 */
	public function save_theme() {
		check_ajax_referer( 'cwpm_nonce', 'nonce' );
		$this->verify_request( 'read' );

		$theme   = sanitize_text_field( wp_unslash( $_POST['theme'] ?? '' ) );
		$allowed = array( 'light', 'dark', 'latte', 'frappe', 'macchiato', 'mocha' );

		if ( ! in_array( $theme, $allowed, true ) ) {
			wp_send_json_error( 'Invalid theme', 400 );
		}

		update_user_meta( get_current_user_id(), 'cwpm_theme_preference', $theme );
		wp_send_json_success( array( 'theme' => $theme ) );
	}

	/**
	 * Save the scan batch size.
	 */
	public function save_batch_size() {
		check_ajax_referer( 'cwpm_nonce', 'nonce' );
		$this->verify_request();

		$batch_size = absint( $_POST['batch_size'] ?? CWPM_SCAN_BATCH_DEFAULT );
		$batch_size = max( CWPM_SCAN_BATCH_MIN, min( CWPM_SCAN_BATCH_MAX, $batch_size ) );

		update_option( 'cwpm_batch_size', $batch_size );
		wp_send_json_success( array( 'batch_size' => $batch_size ) );
	}

	/**
	 * Return current plugin settings.
	 */
	public function get_settings() {
		check_ajax_referer( 'cwpm_nonce', 'nonce' );
		$this->verify_request();

		wp_send_json_success(
			array(
				'batch_size'     => (int) get_option( 'cwpm_batch_size', CWPM_SCAN_BATCH_DEFAULT ),
				'disabled_sizes' => Sizes::get_disabled(),
			)
		);
	}

	/**
	 * Save user display preferences (compact sizes, group by month, per page).
	 */
	public function save_user_prefs() {
		check_ajax_referer( 'cwpm_nonce', 'nonce' );
		$this->verify_request( 'read' );

		$existing = get_user_meta( get_current_user_id(), 'cwpm_user_prefs', true );
		if ( ! is_array( $existing ) ) {
			$existing = array();
		}

		if ( isset( $_POST['compact_sizes'] ) ) {
			$existing['compact_sizes'] = filter_var( wp_unslash( $_POST['compact_sizes'] ), FILTER_VALIDATE_BOOLEAN );
		}
		if ( isset( $_POST['group_by_month'] ) ) {
			$existing['group_by_month'] = filter_var( wp_unslash( $_POST['group_by_month'] ), FILTER_VALIDATE_BOOLEAN );
		}
		if ( isset( $_POST['per_page'] ) ) {
			$existing['per_page'] = absint( $_POST['per_page'] );
		}

		update_user_meta( get_current_user_id(), 'cwpm_user_prefs', $existing );
		wp_send_json_success( $existing );
	}

	/**
	 * Save trash auto-delete setting.
	 *
	 * Stores cwpm_trash_retention_days as 30 (enabled) or 0 (disabled).
	 */
	public function save_trash_settings() {
		check_ajax_referer( 'cwpm_nonce', 'nonce' );
		$this->verify_request();

		$enabled = filter_var(
			isset( $_POST['trash_auto_delete'] ) ? wp_unslash( $_POST['trash_auto_delete'] ) : false,
			FILTER_VALIDATE_BOOLEAN
		);

		$days = $enabled ? 30 : 0;
		update_option( 'cwpm_trash_retention_days', $days );

		wp_send_json_success( array( 'trash_retention_days' => $days ) );
	}

	/**
	 * Persist a pre-scan option toggle.
	 *
	 * Ships with an empty default whitelist (no Pre-Scan Options UI is shown
	 * by the core plugin). Extension plugins may extend the whitelist via the
	 * `cwpm_prescan_options_whitelist` filter as their features boot, and
	 * are responsible for any permission gating before adding their keys.
	 *
	 * Any key NOT in the resolved whitelist is rejected.
	 */
	public function prescan_option_save() {
		check_ajax_referer( 'cwpm_nonce', 'nonce' );
		$this->verify_request();

		/**
		 * Filter the whitelist of pre-scan option keys clients are allowed to toggle.
		 *
		 * @param string[] $keys Option keys allowed via the prescan_option_save AJAX.
		 */
		$allowed = apply_filters(
			'cwpm_prescan_options_whitelist',
			array()
		);
		$key     = isset( $_POST['key'] ) ? sanitize_key( wp_unslash( $_POST['key'] ) ) : '';

		if ( ! in_array( $key, $allowed, true ) ) {
			wp_send_json_error( 'Unknown key.' );
		}

		$value = isset( $_POST['value'] ) ? (bool) (int) $_POST['value'] : false;

		update_option( $key, $value );
		wp_send_json_success(
			array(
				'key'   => $key,
				'value' => $value,
			)
		);
	}
}
