<?php
/**
 * Plugin settings page.
 *
 * @package SubmissionInbox
 */

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

/**
 * Renders and saves plugin settings.
 */
class SUBIN_SettingsPage {
	const NONCE_ACTION = 'subin_save_privacy_settings';
	const NONCE_NAME   = 'subin_privacy_settings_nonce';

	/**
	 * Settings repository.
	 *
	 * @var SUBIN_SettingsRepository
	 */
	private $settings;

	/**
	 * SMTP settings page.
	 *
	 * @var SUBIN_SmtpSettingsPage
	 */
	private $smtp_page;

	/**
	 * Whether state-changing request handling has already run.
	 *
	 * @var bool
	 */
	private $request_handled = false;

	/**
	 * Constructor.
	 *
	 * @param SUBIN_SettingsRepository $settings Settings repository.
	 */
	public function __construct( SUBIN_SettingsRepository $settings ) {
		$this->settings  = $settings;
		$this->smtp_page = new SUBIN_SmtpSettingsPage( $settings );
	}

	/**
	 * Render page.
	 *
	 * @return void
	 */
	public function render() {
		if ( ! current_user_can( SUBIN_AdminMenu::CAPABILITY ) ) {
			wp_die( esc_html__( 'You do not have permission to perform this action.', 'submission-inbox' ) );
		}

		$active_tab = $this->active_tab();
		$this->handle_request();
		$settings = $this->settings->all();

		SUBIN_View::page_header(
			__( 'Settings', 'submission-inbox' ),
			__( 'Manage sending, lead storage, privacy, integrations, and uninstall behavior.', 'submission-inbox' ),
			array( 'wrapper_class' => 'subin-settings-page' )
		);

		settings_errors( 'subin_messages' );
		$this->render_tabs( $active_tab );
		?>
		<div class="subin-settings-panel">
			<?php
			if ( 'sending' === $active_tab ) {
				$this->smtp_page->render_embedded();
			} elseif ( 'integrations' === $active_tab ) {
				$this->render_integrations_tab( $settings );
			} else {
				$this->render_settings_form( $active_tab, $settings );
			}
			?>
		</div>
		<?php
		SUBIN_View::page_footer();
	}

	/**
	 * Handle settings submissions before admin HTML is sent.
	 *
	 * @return void
	 */
	public function handle_request() {
		if ( $this->request_handled ) {
			return;
		}

		$this->request_handled = true;

		if ( ! current_user_can( SUBIN_AdminMenu::CAPABILITY ) ) {
			wp_die( esc_html__( 'You do not have permission to perform this action.', 'submission-inbox' ) );
		}

		$this->smtp_page->maybe_handle_post();
		$this->maybe_save();
	}

	/**
	 * Current settings tab.
	 *
	 * @return string
	 */
	private function active_tab() {
		$tab = SUBIN_Request::get_key( 'subin_settings_tab', 'sending' );
		return array_key_exists( $tab, $this->tabs() ) ? $tab : 'sending';
	}

	/**
	 * Settings tabs.
	 *
	 * @return array<string,string>
	 */
	private function tabs() {
		return array(
			'sending'       => __( 'Sending', 'submission-inbox' ),
			'lead_storage'  => __( 'Lead storage', 'submission-inbox' ),
			'privacy'       => __( 'Privacy', 'submission-inbox' ),
			'spam_protection' => __( 'Spam protection', 'submission-inbox' ),
			'integrations'  => __( 'Integrations', 'submission-inbox' ),
			'uninstall'     => __( 'Uninstall', 'submission-inbox' ),
		);
	}

	/**
	 * Render tabs.
	 *
	 * @param string $active_tab Active tab.
	 * @return void
	 */
	private function render_tabs( $active_tab ) {
		?>
		<nav class="subin-settings-tabs" aria-label="<?php echo esc_attr__( 'Settings sections', 'submission-inbox' ); ?>">
			<?php foreach ( $this->tabs() as $key => $label ) : ?>
				<a class="subin-settings-tab<?php echo $key === $active_tab ? ' subin-settings-tab--active' : ''; ?>" href="<?php echo esc_url( $this->tab_url( $key ) ); ?>"<?php echo $key === $active_tab ? ' aria-current="page"' : ''; ?>>
					<?php echo esc_html( $label ); ?>
				</a>
			<?php endforeach; ?>
		</nav>
		<?php
	}

	/**
	 * Render non-SMTP settings form for one tab.
	 *
	 * @param string              $tab Active tab.
	 * @param array<string,mixed> $settings Settings.
	 * @return void
	 */
	private function render_settings_form( $tab, array $settings ) {
		?>
		<form method="post" action="">
			<input type="hidden" name="subin_settings_action" value="<?php echo esc_attr( $tab ); ?>" />
			<?php wp_nonce_field( self::NONCE_ACTION, self::NONCE_NAME ); ?>
			<?php
			if ( 'lead_storage' === $tab ) {
				$this->render_lead_storage_tab( $settings );
			} elseif ( 'privacy' === $tab ) {
				$this->render_privacy_tab( $settings );
			} elseif ( 'spam_protection' === $tab ) {
				$this->render_spam_protection_tab( $settings );
			} elseif ( 'uninstall' === $tab ) {
				$this->render_uninstall_tab( $settings );
			}
			submit_button( __( 'Save settings', 'submission-inbox' ) );
			?>
		</form>
		<?php
	}

	/**
	 * Lead storage tab.
	 *
	 * @param array<string,mixed> $settings Settings.
	 * @return void
	 */
	private function render_lead_storage_tab( array $settings ) {
		?>
		<div class="subin-settings-section">
			<h2>
				<?php esc_html_e( 'Lead storage', 'submission-inbox' ); ?>
				<?php SUBIN_View::help_tooltip( __( 'When enabled, supported form submissions are saved in Submission Inbox.', 'submission-inbox' ) ); ?>
			</h2>
			<p><?php esc_html_e( 'When enabled, Submission Inbox saves supported form submissions in the WordPress database.', 'submission-inbox' ); ?></p>
			<table class="form-table" role="presentation">
				<tbody>
					<tr>
						<th scope="row"><?php esc_html_e( 'Store form leads', 'submission-inbox' ); ?></th>
						<td>
							<input type="hidden" name="store_leads" value="0" />
							<?php SUBIN_View::checkbox_field( 'store_leads', __( 'Store captured form submissions in the leads inbox', 'submission-inbox' ), (bool) $settings['store_leads'] ); ?>
						</td>
					</tr>
					<tr>
						<th scope="row">
							<label for="subin-retention-days"><?php esc_html_e( 'Retention period', 'submission-inbox' ); ?></label>
							<?php SUBIN_View::help_tooltip( __( 'Automatically removes saved leads after the selected period.', 'submission-inbox' ) ); ?>
						</th>
						<td>
							<select id="subin-retention-days" name="retention_days">
								<?php foreach ( array( 30, 60, 90, 180, 365 ) as $days ) : ?>
									<option value="<?php echo esc_attr( (string) $days ); ?>" <?php selected( absint( $settings['retention_days'] ), $days ); ?>>
										<?php
										printf(
											/* translators: %d: number of retention days. */
											esc_html__( '%d days', 'submission-inbox' ),
											absint( $days )
										);
										?>
									</option>
								<?php endforeach; ?>
								<option value="0" <?php selected( absint( $settings['retention_days'] ), 0 ); ?>><?php esc_html_e( 'Forever', 'submission-inbox' ); ?></option>
							</select>
						</td>
					</tr>
					<tr>
						<th scope="row">
							<label for="subin-new-lead-hours"><?php esc_html_e( 'New lead period', 'submission-inbox' ); ?></label>
						</th>
						<td>
							<select id="subin-new-lead-hours" name="new_lead_hours">
								<?php foreach ( array( 6, 12, 24, 48, 72, 168 ) as $hours ) : ?>
									<option value="<?php echo esc_attr( (string) $hours ); ?>" <?php selected( absint( $settings['new_lead_hours'] ?? 24 ), $hours ); ?>>
										<?php
										if ( $hours < 24 ) {
											printf(
												/* translators: %d: number of hours. */
												esc_html__( '%d hours', 'submission-inbox' ),
												absint( $hours )
											);
										} else {
											printf(
												/* translators: %d: number of days. */
												esc_html( _n( '%d day', '%d days', (int) ( $hours / 24 ), 'submission-inbox' ) ),
												absint( $hours / 24 )
											);
										}
										?>
									</option>
								<?php endforeach; ?>
							</select>
							<p class="description"><?php esc_html_e( 'Inbox summary counts leads as new only inside this window. Seen/unseen status is tracked separately.', 'submission-inbox' ); ?></p>
						</td>
					</tr>
				</tbody>
			</table>
		</div>
		<?php
	}

	/**
	 * Privacy tab.
	 *
	 * @param array<string,mixed> $settings Settings.
	 * @return void
	 */
	private function render_privacy_tab( array $settings ) {
		?>
		<div class="subin-settings-section">
			<h2>
				<?php esc_html_e( 'Privacy', 'submission-inbox' ); ?>
				<?php SUBIN_View::help_tooltip( __( 'Controls whether optional request metadata is stored.', 'submission-inbox' ) ); ?>
			</h2>
			<p><?php esc_html_e( 'Sensitive fields such as passwords, card fields, captcha tokens, and security tokens are not stored by default.', 'submission-inbox' ); ?></p>
			<table class="form-table" role="presentation">
				<tbody>
					<tr>
						<th scope="row"><?php esc_html_e( 'Store IP address', 'submission-inbox' ); ?></th>
						<td>
							<input type="hidden" name="store_ip" value="0" />
							<?php SUBIN_View::checkbox_field( 'store_ip', __( 'Store IP-derived data when enabled', 'submission-inbox' ), (bool) $settings['store_ip'] ); ?>
						</td>
					</tr>
					<tr>
						<th scope="row"><?php esc_html_e( 'Store user agent', 'submission-inbox' ); ?></th>
						<td>
							<input type="hidden" name="store_user_agent" value="0" />
							<?php SUBIN_View::checkbox_field( 'store_user_agent', __( 'Store user-agent-derived data when enabled', 'submission-inbox' ), (bool) $settings['store_user_agent'] ); ?>
						</td>
					</tr>
					<tr>
						<th scope="row"><?php esc_html_e( 'Mask sensitive fields', 'submission-inbox' ); ?></th>
						<td>
							<input type="hidden" name="mask_sensitive_fields" value="0" />
							<?php SUBIN_View::checkbox_field( 'mask_sensitive_fields', __( 'Mask sensitive form fields in administrative views', 'submission-inbox' ), (bool) $settings['mask_sensitive_fields'] ); ?>
						</td>
					</tr>
				</tbody>
			</table>
		</div>
		<?php
	}

	/**
	 * Integrations tab.
	 *
	 * @return void
	 */
	private function render_integrations_tab( array $settings ) {
		$cf7_active     = \SUBIN\Forms\ContactForm7Integration::is_available();
		$wpforms_active = \SUBIN\Forms\WPFormsIntegration::is_available();
		$fluent_active  = \SUBIN\Forms\FluentFormsIntegration::is_available();
		$forminator_active = \SUBIN\Forms\ForminatorIntegration::is_available();
		$ninja_forms_active = \SUBIN\Forms\NinjaFormsIntegration::is_available();
		?>
		<form method="post" action="">
			<input type="hidden" name="subin_settings_action" value="integrations" />
			<?php wp_nonce_field( self::NONCE_ACTION, self::NONCE_NAME ); ?>
			<div class="subin-settings-section">
				<h2><?php esc_html_e( 'Integrations', 'submission-inbox' ); ?></h2>
				<p><?php esc_html_e( 'Enable compatibility only for the form plugins you want Submission Inbox to capture.', 'submission-inbox' ); ?></p>
				<div class="subin-integration-list">
					<?php
					$this->render_integration_card(
						__( 'Contact Form 7 compatibility', 'submission-inbox' ),
						$cf7_active,
						'enable_cf7_integration',
						(bool) $settings['enable_cf7_integration'],
						$cf7_active ? __( 'Submission Inbox can save successful Contact Form 7 submissions in Submission Inbox.', 'submission-inbox' ) : __( 'Install and activate Contact Form 7 to capture Contact Form 7 submissions.', 'submission-inbox' )
					);
					$this->render_integration_card(
						__( 'WPForms compatibility', 'submission-inbox' ),
						$wpforms_active,
						'enable_wpforms_integration',
						(bool) $settings['enable_wpforms_integration'],
						$wpforms_active ? __( 'Submission Inbox can save successful WPForms submissions in Submission Inbox.', 'submission-inbox' ) : __( 'Install and activate WPForms to capture WPForms submissions.', 'submission-inbox' )
					);
					$this->render_integration_card(
						__( 'Fluent Forms compatibility', 'submission-inbox' ),
						$fluent_active,
						'enable_fluent_forms_integration',
						(bool) $settings['enable_fluent_forms_integration'],
						$fluent_active ? __( 'Submission Inbox can save successful Fluent Forms submissions in Submission Inbox.', 'submission-inbox' ) : __( 'Install and activate Fluent Forms to capture Fluent Forms submissions.', 'submission-inbox' )
					);
					$this->render_integration_card(
						__( 'Forminator compatibility', 'submission-inbox' ),
						$forminator_active,
						'enable_forminator_integration',
						(bool) $settings['enable_forminator_integration'],
						$forminator_active ? __( 'Submission Inbox can save successful Forminator submissions in Submission Inbox.', 'submission-inbox' ) : __( 'Install and activate Forminator to capture Forminator submissions.', 'submission-inbox' )
					);
					$this->render_integration_card(
						__( 'Ninja Forms compatibility', 'submission-inbox' ),
						$ninja_forms_active,
						'enable_ninja_forms_integration',
						(bool) $settings['enable_ninja_forms_integration'],
						$ninja_forms_active ? __( 'Submission Inbox can save successful Ninja Forms submissions in Submission Inbox.', 'submission-inbox' ) : __( 'Install and activate Ninja Forms to capture Ninja Forms submissions.', 'submission-inbox' )
					);
					$this->render_planned_integration_card(
						__( 'Gravity Forms compatibility', 'submission-inbox' ),
						__( 'Gravity Forms lead capture compatibility is planned for a future update.', 'submission-inbox' )
					);
					?>
				</div>
			</div>
			<?php submit_button( __( 'Save settings', 'submission-inbox' ) ); ?>
		</form>
		<?php
	}

	/**
	 * Spam protection tab.
	 *
	 * @param array<string,mixed> $settings Settings.
	 * @return void
	 */
	private function render_spam_protection_tab( array $settings ) {
		?>
		<div class="subin-settings-section">
			<h2><?php esc_html_e( 'Google reCAPTCHA', 'submission-inbox' ); ?></h2>
			<p><?php esc_html_e( 'Use Google reCAPTCHA v3 to verify built-in Submission Inbox form submissions before leads are saved.', 'submission-inbox' ); ?></p>
			<?php if ( ! empty( $settings['recaptcha_enabled'] ) && ( '' === trim( (string) $settings['recaptcha_site_key'] ) || '' === trim( (string) $settings['recaptcha_secret_key'] ) ) ) : ?>
				<div class="notice notice-warning inline subin-settings-warning">
					<p><?php esc_html_e( 'Google reCAPTCHA is enabled, but the Site Key or Secret Key is missing.', 'submission-inbox' ); ?></p>
				</div>
			<?php endif; ?>
			<table class="form-table" role="presentation">
				<tbody>
					<tr>
						<th scope="row"><?php esc_html_e( 'Enable Google reCAPTCHA', 'submission-inbox' ); ?></th>
						<td>
							<input type="hidden" name="recaptcha_enabled" value="0" />
							<?php SUBIN_View::checkbox_field( 'recaptcha_enabled', __( 'Verify built-in form submissions with Google reCAPTCHA v3 before saving leads.', 'submission-inbox' ), (bool) $settings['recaptcha_enabled'] ); ?>
						</td>
					</tr>
					<tr>
						<th scope="row">
							<label for="subin-recaptcha-site-key"><?php esc_html_e( 'Site Key', 'submission-inbox' ); ?></label>
						</th>
						<td>
							<input id="subin-recaptcha-site-key" class="regular-text" type="text" name="recaptcha_site_key" value="<?php echo esc_attr( $settings['recaptcha_site_key'] ); ?>" autocomplete="off" />
							<p class="description"><?php esc_html_e( 'Used on the frontend to request a reCAPTCHA token.', 'submission-inbox' ); ?></p>
						</td>
					</tr>
					<tr>
						<th scope="row">
							<label for="subin-recaptcha-secret-key"><?php esc_html_e( 'Secret Key', 'submission-inbox' ); ?></label>
						</th>
						<td>
							<input id="subin-recaptcha-secret-key" class="regular-text" type="password" name="recaptcha_secret_key" value="<?php echo esc_attr( $settings['recaptcha_secret_key'] ); ?>" autocomplete="off" />
							<p class="description"><?php esc_html_e( 'Used server-side to verify the reCAPTCHA token with Google.', 'submission-inbox' ); ?></p>
						</td>
					</tr>
					<tr>
						<th scope="row">
							<label for="subin-recaptcha-score-threshold"><?php esc_html_e( 'Score threshold', 'submission-inbox' ); ?></label>
						</th>
						<td>
							<input id="subin-recaptcha-score-threshold" type="number" name="recaptcha_score_threshold" value="<?php echo esc_attr( (string) $settings['recaptcha_score_threshold'] ); ?>" min="0" max="1" step="0.1" />
							<p class="description"><?php esc_html_e( 'Submissions below this score are blocked. Higher values are stricter.', 'submission-inbox' ); ?></p>
						</td>
					</tr>
				</tbody>
			</table>
		</div>
		<?php
	}

	/**
	 * Render one integration card.
	 *
	 * @param string $title Card title.
	 * @param bool   $detected Whether plugin is detected.
	 * @param string $setting_key Setting key.
	 * @param bool   $enabled Whether integration is enabled.
	 * @param string $description Card description.
	 * @return void
	 */
	private function render_integration_card( $title, $detected, $setting_key, $enabled, $description ) {
		?>
		<div class="subin-integration-card">
			<div>
				<h3><?php echo esc_html( $title ); ?></h3>
				<p><?php echo esc_html( $description ); ?></p>
			</div>
			<div class="subin-integration-card__controls">
				<?php SUBIN_View::badge( $detected ? __( 'Detected', 'submission-inbox' ) : __( 'Not detected', 'submission-inbox' ), $detected ? 'success' : 'muted' ); ?>
				<?php if ( $detected ) : ?>
					<input type="hidden" name="<?php echo esc_attr( $setting_key ); ?>" value="0" />
				<?php endif; ?>
				<div class="subin-integration-card__toggle">
					<?php SUBIN_View::checkbox_field( $setting_key, __( 'Enabled', 'submission-inbox' ), $detected && $enabled, '', ! $detected ); ?>
					<?php SUBIN_View::help_tooltip( __( 'When disabled, submissions from this integration are not saved to Inbox or Email Log.', 'submission-inbox' ), __( 'Integration storage', 'submission-inbox' ) ); ?>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Render one planned integration card.
	 *
	 * @param string $title Card title.
	 * @param string $description Card description.
	 * @return void
	 */
	private function render_planned_integration_card( $title, $description ) {
		?>
		<div class="subin-integration-card subin-integration-card--planned">
			<div>
				<h3><?php echo esc_html( $title ); ?></h3>
				<p><?php echo esc_html( $description ); ?></p>
			</div>
			<div class="subin-integration-card__controls">
				<?php SUBIN_View::badge( __( 'Planned', 'submission-inbox' ), 'muted' ); ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Uninstall tab.
	 *
	 * @param array<string,mixed> $settings Settings.
	 * @return void
	 */
	private function render_uninstall_tab( array $settings ) {
		?>
		<div class="subin-settings-section">
			<h2>
				<?php esc_html_e( 'Uninstall', 'submission-inbox' ); ?>
				<?php SUBIN_View::help_tooltip( __( 'If enabled, plugin tables and settings are deleted when the plugin is uninstalled.', 'submission-inbox' ) ); ?>
			</h2>
			<p><?php esc_html_e( 'If enabled, plugin tables and settings will be removed when the plugin is deleted.', 'submission-inbox' ); ?></p>
			<table class="form-table" role="presentation">
				<tbody>
					<tr>
						<th scope="row"><?php esc_html_e( 'Delete plugin data on uninstall', 'submission-inbox' ); ?></th>
						<td>
							<input type="hidden" name="delete_data_on_uninstall" value="0" />
							<?php SUBIN_View::checkbox_field( 'delete_data_on_uninstall', __( 'Remove Submission Inbox tables and settings when the plugin is uninstalled', 'submission-inbox' ), (bool) $settings['delete_data_on_uninstall'] ); ?>
							<p class="description"><?php esc_html_e( 'Deactivation never deletes data. This setting applies only when the plugin is uninstalled.', 'submission-inbox' ); ?></p>
						</td>
					</tr>
				</tbody>
			</table>
		</div>
		<?php
	}

	/**
	 * Tab URL.
	 *
	 * @param string $tab Tab key.
	 * @return string
	 */
	private function tab_url( $tab ) {
		return add_query_arg(
			array(
				'page'             => 'subin-settings',
				'subin_settings_tab' => sanitize_key( $tab ),
			),
			admin_url( 'admin.php' )
		);
	}

	/**
	 * Save settings when the form is submitted.
	 *
	 * @return void
	 */
	private function maybe_save() {
		$request_method = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ?? '' ) );
		if ( 'POST' !== strtoupper( $request_method ) || isset( $_POST['subin_smtp_action'] ) ) {
			return;
		}

		if ( ! isset( $_POST[ self::NONCE_NAME ] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ self::NONCE_NAME ] ) ), self::NONCE_ACTION ) ) {
			add_settings_error(
				'subin_messages',
				'subin_security_check_failed',
				__( 'Security check failed. Please try again.', 'submission-inbox' ),
				'error'
			);
			return;
		}

		$action   = sanitize_key( wp_unslash( $_POST['subin_settings_action'] ?? '' ) );
		$settings = $this->settings->all();

		if ( 'lead_storage' === $action ) {
			$settings['store_leads']     = rest_sanitize_boolean( wp_unslash( $_POST['store_leads'] ?? false ) );
			$settings['retention_days']  = $this->sanitize_retention_days( sanitize_text_field( wp_unslash( $_POST['retention_days'] ?? 90 ) ) );
			$settings['new_lead_hours']  = $this->sanitize_new_lead_hours( sanitize_text_field( wp_unslash( $_POST['new_lead_hours'] ?? 24 ) ) );
		} elseif ( 'integrations' === $action ) {
			if ( \SUBIN\Forms\ContactForm7Integration::is_available() ) {
				$settings['enable_cf7_integration'] = rest_sanitize_boolean( wp_unslash( $_POST['enable_cf7_integration'] ?? false ) );
			}
			if ( \SUBIN\Forms\WPFormsIntegration::is_available() ) {
				$settings['enable_wpforms_integration'] = rest_sanitize_boolean( wp_unslash( $_POST['enable_wpforms_integration'] ?? false ) );
			}
			if ( \SUBIN\Forms\FluentFormsIntegration::is_available() ) {
				$settings['enable_fluent_forms_integration'] = rest_sanitize_boolean( wp_unslash( $_POST['enable_fluent_forms_integration'] ?? false ) );
			}
			if ( \SUBIN\Forms\ForminatorIntegration::is_available() ) {
				$settings['enable_forminator_integration'] = rest_sanitize_boolean( wp_unslash( $_POST['enable_forminator_integration'] ?? false ) );
			}
			if ( \SUBIN\Forms\NinjaFormsIntegration::is_available() ) {
				$settings['enable_ninja_forms_integration'] = rest_sanitize_boolean( wp_unslash( $_POST['enable_ninja_forms_integration'] ?? false ) );
			}
		} elseif ( 'privacy' === $action ) {
			$settings['store_ip']              = rest_sanitize_boolean( wp_unslash( $_POST['store_ip'] ?? false ) );
			$settings['store_user_agent']      = rest_sanitize_boolean( wp_unslash( $_POST['store_user_agent'] ?? false ) );
			$settings['mask_sensitive_fields'] = rest_sanitize_boolean( wp_unslash( $_POST['mask_sensitive_fields'] ?? false ) );
		} elseif ( 'spam_protection' === $action ) {
			$settings['recaptcha_enabled']         = rest_sanitize_boolean( wp_unslash( $_POST['recaptcha_enabled'] ?? false ) );
			$settings['recaptcha_site_key']        = sanitize_text_field( trim( (string) wp_unslash( $_POST['recaptcha_site_key'] ?? '' ) ) );
			$settings['recaptcha_secret_key']      = sanitize_text_field( trim( (string) wp_unslash( $_POST['recaptcha_secret_key'] ?? '' ) ) );
			$settings['recaptcha_score_threshold'] = $this->sanitize_recaptcha_score_threshold( wp_unslash( $_POST['recaptcha_score_threshold'] ?? 0.5 ) );
		} elseif ( 'uninstall' === $action ) {
			$settings['delete_data_on_uninstall'] = rest_sanitize_boolean( wp_unslash( $_POST['delete_data_on_uninstall'] ?? false ) );
		} else {
			return;
		}

		update_option( SUBIN_SettingsRepository::OPTION_KEY, $settings, false );

		add_settings_error(
			'subin_messages',
			'subin_settings_saved',
			__( 'Settings saved.', 'submission-inbox' ),
			'updated'
		);
	}

	/**
	 * Sanitize retention days.
	 *
	 * @param mixed $value Raw value.
	 * @return int
	 */
	private function sanitize_retention_days( $value ) {
		$value   = absint( $value );
		$allowed = array( 0, 30, 60, 90, 180, 365 );

		return in_array( $value, $allowed, true ) ? $value : 90;
	}

	/**
	 * Sanitize the unread lead freshness window.
	 *
	 * @param mixed $value Raw value.
	 * @return int
	 */
	private function sanitize_new_lead_hours( $value ) {
		$value   = absint( $value );
		$allowed = array( 6, 12, 24, 48, 72, 168 );

		return in_array( $value, $allowed, true ) ? $value : 24;
	}

	/**
	 * Sanitize reCAPTCHA score threshold.
	 *
	 * @param mixed $value Raw value.
	 * @return float
	 */
	private function sanitize_recaptcha_score_threshold( $value ) {
		$value = is_numeric( $value ) ? (float) $value : 0.5;

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