<?php
/**
 * SMTP configuration helpers.
 *
 * @package MailDoctor
 */

namespace MailDoctor\Mail\Config;

use MailDoctor\Helpers\Sanitize;

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

/**
 * Provides defaults and sanitization for SMTP-related settings.
 */
class SMTP_Config {

	/**
	 * Default SMTP-oriented settings.
	 *
	 * @return array<string, mixed>
	 */
	public static function defaults(): array {
		return array(
			'smtp_host'             => '',
			'smtp_port'             => 587,
			'smtp_encryption'       => 'tls',
			'smtp_username'         => '',
			'smtp_password'         => '',
			'transport'             => 'smtp',
			'from_email'            => '',
			'from_name'             => '',
			'force_from_email_lock' => false,
			'force_from_name_lock'  => false,
		);
	}

	/**
	 * Sanitize SMTP configuration payload.
	 *
	 * @param array<string, mixed> $data     Incoming values.
	 * @param array<string, mixed> $current  Existing saved values.
	 * @return array<string, mixed>
	 */
	public static function sanitize( array $data, array $current ): array {
		$current = wp_parse_args( $current, self::defaults() );

		$password = $current['smtp_password'] ?? '';
		if ( array_key_exists( 'smtp_password', $data ) ) {
			$incoming = trim( (string) $data['smtp_password'] );
			if ( '' !== $incoming ) {
				$password = $incoming;
			}
		}

		return array(
			'smtp_host'             => sanitize_text_field( $data['smtp_host'] ?? $current['smtp_host'] ),
			'smtp_port'             => isset( $data['smtp_port'] ) ? max( 1, Sanitize::int( $data['smtp_port'], 587 ) ) : (int) $current['smtp_port'],
			'smtp_encryption'       => self::sanitize_encryption( $data['smtp_encryption'] ?? $current['smtp_encryption'] ),
			'smtp_username'         => sanitize_text_field( $data['smtp_username'] ?? $current['smtp_username'] ),
			'smtp_password'         => (string) $password,
			'transport'             => self::sanitize_transport( $data['transport'] ?? $current['transport'] ),
			'from_email'            => sanitize_email( $data['from_email'] ?? $current['from_email'] ),
			'from_name'             => sanitize_text_field( $data['from_name'] ?? $current['from_name'] ),
			'force_from_email_lock' => isset( $data['force_from_email_lock'] ) ? Sanitize::bool( $data['force_from_email_lock'] ) : (bool) $current['force_from_email_lock'],
			'force_from_name_lock'  => isset( $data['force_from_name_lock'] ) ? Sanitize::bool( $data['force_from_name_lock'] ) : (bool) $current['force_from_name_lock'],
		);
	}

	/**
	 * Sanitize encryption value.
	 *
	 * @param string $encryption Raw value.
	 * @return string
	 */
	private static function sanitize_encryption( string $encryption ): string {
		$allowed    = array( 'none', 'ssl', 'tls' );
		$encryption = strtolower( sanitize_text_field( $encryption ) );

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

	/**
	 * Sanitize transport selection.
	 *
	 * @param string $transport Raw value.
	 * @return string
	 */
	private static function sanitize_transport( string $transport ): string {
		$allowed   = array( 'smtp', 'mailgun_api', 'sendgrid_api', 'postmark_api', 'sparkpost_api', 'ses_api', 'generic_http' );
		$transport = strtolower( sanitize_text_field( $transport ) );

		return in_array( $transport, $allowed, true ) ? $transport : 'smtp';
	}
}
