<?php
/**
 * Settings Registration
 *
 * Registers WordPress settings with proper sanitization.
 *
 * @package AmbassadorHub\Admin\Settings
 */

namespace AmbassadorHub\Admin\Settings;

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

use function absint;
use function add_action;
use function get_option;
use function get_permalink;
use function home_url;
use function register_setting;

/**
 * Handles WordPress settings registration.
 *
 * Registers all custom settings with proper sanitization callbacks.
 */
final class Registration {
	/**
	 * Initialize settings registration.
	 *
	 * @return void
	 */
	public static function init(): void {
		add_action( 'init', array( self::class, 'register_settings' ) );
	}

	/**
	 * Register all custom settings.
	 *
	 * @return void
	 */
	public static function register_settings(): void {
		// Register connector slot options used by ConnectorRegistry.
		$connector_slot_args = array(
			'sanitize_callback' => 'sanitize_key',
			'default'           => '',
			'type'              => 'string',
		);
		register_setting( 'ambh_integrations', 'ambh_active_connector_psp', $connector_slot_args );
		register_setting( 'ambh_integrations', 'ambh_active_connector_crm', $connector_slot_args );
		register_setting( 'ambh_integrations', 'ambh_active_connector_marketing_automation', $connector_slot_args );

		// Page settings — all registered under ambh_advanced so the
		// settings_fields('ambh_advanced') nonce covers them all.
		register_setting(
			'ambh_advanced',
			'ambh_psp_redirect_page_id',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_page_id' ),
				'default'           => 0,
				'type'              => 'integer',
			)
		);

		// Analytics event tracking (dataLayer/GTM push) — opt-in, off by default.
		// See Tracking\DataLayerQueue, which reads this option before setting the
		// ambh_tk cookie or queuing any event.
		register_setting(
			'ambh_advanced',
			'ambh_analytics_tracking_enabled',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_checkbox' ),
				'default'           => false,
				'type'              => 'boolean',
			)
		);

		// Spam Protection — see AmbassadorHub\Spam\SpamShield, which reads these
		// options. Every check defaults to on; nothing here contacts an
		// external service.
		register_setting(
			'ambh_spam',
			'ambh_spam_honeypot_enabled',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_checkbox' ),
				'default'           => true,
				'type'              => 'boolean',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_min_submit_seconds',
			array(
				'sanitize_callback' => 'absint',
				'default'           => 3,
				'type'              => 'integer',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_rate_limiting_enabled',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_checkbox' ),
				'default'           => true,
				'type'              => 'boolean',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_signup_rate_limit',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_positive_int' ),
				'default'           => 5,
				'type'              => 'integer',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_donation_rate_limit',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_positive_int' ),
				'default'           => 50,
				'type'              => 'integer',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_email_filter_enabled',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_checkbox' ),
				'default'           => true,
				'type'              => 'boolean',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_blocked_email_domains',
			array(
				'sanitize_callback' => 'sanitize_textarea_field',
				'default'           => '',
				'type'              => 'string',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_content_filter_enabled',
			array(
				'sanitize_callback' => array( self::class, 'sanitize_checkbox' ),
				'default'           => true,
				'type'              => 'boolean',
			)
		);
		register_setting(
			'ambh_spam',
			'ambh_spam_max_links_in_message',
			array(
				'sanitize_callback' => 'absint',
				'default'           => 2,
				'type'              => 'integer',
			)
		);

		do_action( 'ambh_register_settings' );
	}

	/**
	 * Sanitize page ID.
	 *
	 * Uses absint() rather than a plain (int) cast so negative values can't
	 * pass through — page IDs are never negative.
	 *
	 * @param mixed $value The value to sanitize.
	 *
	 * @return int Sanitized page ID.
	 */
	public static function sanitize_page_id( $value ): int {
		return absint( $value );
	}

	/**
	 * Sanitize boolean settings.
	 *
	 * @param mixed $value Raw value.
	 *
	 * @return bool
	 */
	public static function sanitize_boolean( $value ): bool {
		return (bool) $value;
	}

	/**
	 * Sanitize checkbox value.
	 *
	 * @param mixed $value Raw value.
	 *
	 * @return bool
	 */
	public static function sanitize_checkbox( $value ): bool {
		return '1' === $value || 1 === $value || true === $value;
	}

	/**
	 * Sanitize a "must be at least 1" integer setting (e.g. a rate limit).
	 *
	 * @param mixed $value Raw value.
	 *
	 * @return int
	 */
	public static function sanitize_positive_int( $value ): int {
		return max( 1, absint( $value ) );
	}

	/**
	 * Get the configured post-payment redirect URL.
	 *
	 * Resolution order:
	 *   1. get_permalink() of ambh_psp_redirect_page_id (page-selector setting)
	 *   2. Legacy ambh_psp_redirect_url plain-text value (back-compat)
	 *   3. home_url() fallback
	 *
	 * All PSP connectors should call this instead of reading the option directly.
	 *
	 * @return string Absolute URL.
	 */
	public static function get_redirect_url(): string {
		$page_id = (int) get_option( 'ambh_psp_redirect_page_id', 0 );
		if ( $page_id ) {
			$url = get_permalink( $page_id );
			if ( $url ) {
				return (string) $url;
			}
		}
		return home_url();
	}
}
