<?php
/**
 * Plugin settings.
 *
 * @package TechDexSearchScrapeGuard
 */

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

final class TDSSG_Settings {
	const OPTION_KEY = 'tdssg_settings';

	/**
	 * Return the default settings.
	 *
	 * @return array
	 */
	public static function defaults() {
		return array(
			'enabled'                    => 1,
			'max_length'                 => 100,
			'max_words'                  => 12,
			'max_page'                   => 15,
			'logged_in_max_page'         => 50,
			'block_chrome_30'            => 1,
			'rate_limit'                 => 6,
			'rate_window'                => 60,
			'cooldown'                   => 600,
			'require_verification'       => 0,
			'turnstile_site_key'         => '',
			'turnstile_secret_key'       => '',
			'verified_cookie_lifetime'   => 600,
			'add_robots_directives'      => 1,
			'ensure_search_noindex'      => 1,
		);
	}

	/**
	 * Return merged settings.
	 *
	 * @return array
	 */
	public static function get_all() {
		$saved = get_option( self::OPTION_KEY, array() );

		if ( ! is_array( $saved ) ) {
			$saved = array();
		}

		return wp_parse_args( $saved, self::defaults() );
	}

	/**
	 * Return one setting.
	 *
	 * @param string $key Setting key.
	 * @return mixed
	 */
	public static function get( $key ) {
		$settings = self::get_all();

		return isset( $settings[ $key ] ) ? $settings[ $key ] : null;
	}

	/**
	 * Sanitize the complete settings payload.
	 *
	 * @param mixed $input Submitted settings.
	 * @return array
	 */
	public static function sanitize( $input ) {
		$input    = is_array( $input ) ? $input : array();
		$defaults = self::defaults();
		$output   = array();

		foreach ( array( 'enabled', 'block_chrome_30', 'require_verification', 'add_robots_directives', 'ensure_search_noindex' ) as $checkbox ) {
			$output[ $checkbox ] = empty( $input[ $checkbox ] ) ? 0 : 1;
		}

		$output['max_length']               = self::bounded_int( $input, 'max_length', $defaults['max_length'], 20, 500 );
		$output['max_words']                = self::bounded_int( $input, 'max_words', $defaults['max_words'], 2, 50 );
		$output['max_page']                 = self::bounded_int( $input, 'max_page', $defaults['max_page'], 1, 100 );
		$output['logged_in_max_page']       = self::bounded_int( $input, 'logged_in_max_page', $defaults['logged_in_max_page'], 1, 200 );
		$output['logged_in_max_page']       = max( $output['max_page'], $output['logged_in_max_page'] );
		$output['rate_limit']               = self::bounded_int( $input, 'rate_limit', $defaults['rate_limit'], 1, 120 );
		$output['rate_window']              = self::bounded_int( $input, 'rate_window', $defaults['rate_window'], 10, 3600 );
		$output['cooldown']                 = self::bounded_int( $input, 'cooldown', $defaults['cooldown'], 30, 86400 );
		$output['verified_cookie_lifetime'] = self::bounded_int( $input, 'verified_cookie_lifetime', $defaults['verified_cookie_lifetime'], 60, 86400 );
		$output['turnstile_site_key']       = isset( $input['turnstile_site_key'] ) ? sanitize_text_field( wp_unslash( $input['turnstile_site_key'] ) ) : '';
		$output['turnstile_secret_key']     = isset( $input['turnstile_secret_key'] ) ? sanitize_text_field( wp_unslash( $input['turnstile_secret_key'] ) ) : '';

		return $output;
	}

	/**
	 * Clamp an integer setting.
	 *
	 * @param array  $input   Submitted settings.
	 * @param string $key     Setting key.
	 * @param int    $default Default value.
	 * @param int    $min     Minimum.
	 * @param int    $max     Maximum.
	 * @return int
	 */
	private static function bounded_int( $input, $key, $default, $min, $max ) {
		$value = isset( $input[ $key ] ) ? absint( $input[ $key ] ) : $default;

		return max( $min, min( $max, $value ) );
	}
}
