<?php
/**
 * Settings storage.
 *
 * @package SubmissionInbox
 */

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

/**
 * Reads and writes plugin settings.
 */
class SUBIN_SettingsRepository {
	const OPTION_KEY = 'subin_settings';

	/**
	 * Get default settings.
	 *
	 * @return array<string,mixed>
	 */
	public static function defaults() {
		return array(
			'enable_smtp'              => false,
			'from_email'               => '',
			'from_name'                => '',
			'smtp_host'                => '',
			'smtp_port'                => 587,
			'smtp_encryption'          => 'tls',
			'smtp_auth'                => true,
			'smtp_username'            => '',
			'smtp_password'            => '',
			'store_leads'              => true,
			'retention_days'           => 90,
			'new_lead_hours'           => 24,
			'delete_data_on_uninstall' => false,
			'store_ip'                 => false,
			'store_user_agent'         => false,
			'enable_cf7_integration'   => true,
			'enable_wpforms_integration' => true,
			'enable_fluent_forms_integration' => true,
			'enable_forminator_integration' => true,
			'enable_ninja_forms_integration' => true,
			'recaptcha_enabled'        => false,
			'recaptcha_site_key'       => '',
			'recaptcha_secret_key'     => '',
			'recaptcha_score_threshold' => 0.5,
			'mask_sensitive_fields'        => true,
			'notification_recipient_email' => is_email( get_option( 'admin_email' ) ) ? get_option( 'admin_email' ) : '',
			'notification_from_lead_email' => false,
			'cloud_sync_enabled'           => false,
			'cloud_sync_data_mode'         => 'lead_summary',
			'cloud_sync_endpoint'          => 'https://inboxmend.com/api/v1/plugin',
			'cloud_sync_site_key'          => '',
			'cloud_sync_license_key'       => '',
			'cloud_sync_site_token'        => '',
			'cloud_sync_transport'         => 'polling',
			'cloud_sync_polling_enabled'   => false,
			'cloud_sync_allowed_mode'      => '',
			'cloud_sync_full_data_enabled' => false,
			'cloud_sync_full_data_consent' => false,
			'cloud_sync_connection_status' => 'disconnected',
			'cloud_sync_site_id'           => 0,
			'cloud_sync_license_status'    => '',
			'cloud_sync_license_site_limit' => 0,
			'cloud_sync_heartbeat_interval' => 300,
			'cloud_sync_last_heartbeat_at' => '',
			'cloud_sync_last_sync_at'      => '',
			'cloud_sync_last_sync_error'   => '',
		);
	}

	/**
	 * Add default option if missing.
	 *
	 * @return void
	 */
	public static function ensure_defaults() {
		if ( false === get_option( self::OPTION_KEY, false ) ) {
			add_option( self::OPTION_KEY, self::defaults(), '', false );
		}
	}

	/**
	 * Get all settings merged with defaults.
	 *
	 * @return array<string,mixed>
	 */
	public function all() {
		$settings = get_option( self::OPTION_KEY, array() );

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

		return array_merge( self::defaults(), $settings );
	}

	/**
	 * Update SMTP settings.
	 *
	 * @param array<string,mixed> $data Submitted data.
	 * @return true|\WP_Error
	 */
	public function update_smtp_settings( array $data ) {
		$settings = $this->all();
		$raw_from_email = trim( (string) wp_unslash( $data['from_email'] ?? '' ) );
		$from_email     = sanitize_email( $raw_from_email );
		$raw_default_recipient = trim( (string) wp_unslash( $data['notification_recipient_email'] ?? '' ) );
		$default_recipient     = sanitize_email( $raw_default_recipient );

		if ( '' !== $raw_from_email && ! is_email( $raw_from_email ) ) {
			return new WP_Error(
				'subin_invalid_from_email',
				__( 'From Email must be a valid email address.', 'submission-inbox' )
			);
		}

		if ( '' === $from_email && ! is_email( get_option( 'admin_email' ) ) ) {
			return new WP_Error(
				'subin_invalid_from_email',
				__( 'From Email must be a valid email address.', 'submission-inbox' )
			);
		}

		if ( '' !== $raw_default_recipient && ! is_email( $raw_default_recipient ) ) {
			return new WP_Error(
				'subin_invalid_default_notification_recipient',
				__( 'Default admin notification recipient must be a valid email address.', 'submission-inbox' )
			);
		}

		if ( '' === $default_recipient ) {
			$admin_email = sanitize_email( (string) get_option( 'admin_email' ) );
			$default_recipient = is_email( $admin_email ) ? $admin_email : '';
		}

		$settings['enable_smtp']     = $this->sanitize_bool( $data['enable_smtp'] ?? false );
		$settings['from_email']      = $from_email;
		$settings['from_name']       = sanitize_text_field( wp_unslash( $data['from_name'] ?? '' ) );
		$settings['notification_recipient_email'] = $default_recipient;
		$settings['smtp_host']       = sanitize_text_field( wp_unslash( $data['smtp_host'] ?? '' ) );
		$settings['smtp_port']       = max( 1, min( 65535, absint( $data['smtp_port'] ?? 587 ) ) );
		$settings['smtp_encryption'] = $this->sanitize_encryption( $data['smtp_encryption'] ?? 'tls' );
		$settings['smtp_auth']       = $this->sanitize_bool( $data['smtp_auth'] ?? false );
		$settings['smtp_username']   = sanitize_text_field( wp_unslash( $data['smtp_username'] ?? '' ) );

		if ( array_key_exists( 'smtp_password', $data ) ) {
			$password = (string) wp_unslash( $data['smtp_password'] );
			if ( '' !== $password ) {
				$settings['smtp_password'] = sanitize_text_field( $password );
			}
		}

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

		return true;
	}

	/**
	 * Update privacy and retention settings.
	 *
	 * @param array<string,mixed> $data Submitted data.
	 * @return void
	 */
	public function update_privacy_settings( array $data ) {
		$settings = $this->all();

		$settings['store_leads']              = $this->sanitize_bool( $data['store_leads'] ?? false );
		$settings['retention_days']           = $this->sanitize_retention_days( $data['retention_days'] ?? 90 );
		$settings['new_lead_hours']           = $this->sanitize_new_lead_hours( $data['new_lead_hours'] ?? 24 );
		$settings['store_ip']                 = $this->sanitize_bool( $data['store_ip'] ?? false );
		$settings['store_user_agent']         = $this->sanitize_bool( $data['store_user_agent'] ?? false );
		$settings['mask_sensitive_fields']    = $this->sanitize_bool( $data['mask_sensitive_fields'] ?? false );
		$settings['delete_data_on_uninstall'] = $this->sanitize_bool( $data['delete_data_on_uninstall'] ?? false );

		update_option( self::OPTION_KEY, $settings, false );
	}

	/**
	 * Sanitize encryption value.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	private function sanitize_encryption( $value ) {
		$value   = sanitize_key( wp_unslash( $value ) );
		$allowed = array( 'none', 'ssl', 'tls' );

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

	/**
	 * Sanitize a boolean-like setting.
	 *
	 * @param mixed $value Raw value.
	 * @return bool
	 */
	private function sanitize_bool( $value ) {
		return rest_sanitize_boolean( $value );
	}

	/**
	 * Sanitize retention period.
	 *
	 * @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;
	}
}
