<?php
/**
 * API transport configuration helpers.
 *
 * @package MailDoctor
 */

namespace MailDoctor\Mail\Config;

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

/**
 * Provides defaults and sanitization for API transport credentials.
 */
class API_Config {

	/**
	 * Default API credentials.
	 *
	 * @return array<string, mixed>
	 */
	public static function defaults(): array {
		return array(
			'mailgun_api_key'        => '',
			'mailgun_api_domain'     => '',
			'mailgun_api_endpoint'   => 'api.mailgun.net',
			'sendgrid_api_key'       => '',
			'postmark_api_token'     => '',
			'sparkpost_api_key'      => '',
			'sparkpost_api_endpoint' => 'https://api.sparkpost.com',
			'ses_api_key'            => '',
			'ses_api_secret'         => '',
			'ses_api_session_token'  => '',
			'ses_api_region'         => 'us-east-1',
			'generic_api_endpoint'   => '',
			'generic_api_method'     => 'POST',
			'generic_api_auth_token' => '',
		);
	}

	/**
	 * Sanitize API 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() );

		$result = self::defaults();

		$result['mailgun_api_key']      = isset( $data['mailgun_api_key'] ) ? trim( (string) $data['mailgun_api_key'] ) : ( $current['mailgun_api_key'] ?? $result['mailgun_api_key'] );
		$result['mailgun_api_domain']   = sanitize_text_field( $data['mailgun_api_domain'] ?? ( $current['mailgun_api_domain'] ?? $result['mailgun_api_domain'] ) );
		$result['mailgun_api_endpoint'] = sanitize_text_field( $data['mailgun_api_endpoint'] ?? ( $current['mailgun_api_endpoint'] ?? $result['mailgun_api_endpoint'] ) );

		$result['sendgrid_api_key'] = isset( $data['sendgrid_api_key'] ) && '' !== $data['sendgrid_api_key']
			? trim( (string) $data['sendgrid_api_key'] )
			: ( $current['sendgrid_api_key'] ?? $result['sendgrid_api_key'] );

		$result['postmark_api_token'] = isset( $data['postmark_api_token'] ) && '' !== $data['postmark_api_token']
			? trim( (string) $data['postmark_api_token'] )
			: ( $current['postmark_api_token'] ?? $result['postmark_api_token'] );

		$result['sparkpost_api_key'] = isset( $data['sparkpost_api_key'] ) && '' !== $data['sparkpost_api_key']
			? trim( (string) $data['sparkpost_api_key'] )
			: ( $current['sparkpost_api_key'] ?? $result['sparkpost_api_key'] );

		$result['sparkpost_api_endpoint'] = esc_url_raw( $data['sparkpost_api_endpoint'] ?? ( $current['sparkpost_api_endpoint'] ?? $result['sparkpost_api_endpoint'] ) );

		$result['ses_api_key'] = isset( $data['ses_api_key'] ) && '' !== $data['ses_api_key']
			? trim( (string) $data['ses_api_key'] )
			: ( $current['ses_api_key'] ?? $result['ses_api_key'] );

		$result['ses_api_secret'] = isset( $data['ses_api_secret'] ) && '' !== $data['ses_api_secret']
			? wp_unslash( (string) $data['ses_api_secret'] )
			: ( $current['ses_api_secret'] ?? $result['ses_api_secret'] );

		$result['ses_api_session_token'] = isset( $data['ses_api_session_token'] ) && '' !== $data['ses_api_session_token']
			? trim( (string) $data['ses_api_session_token'] )
			: ( $current['ses_api_session_token'] ?? $result['ses_api_session_token'] );

		$result['ses_api_region'] = self::sanitize_ses_region( $data['ses_api_region'] ?? ( $current['ses_api_region'] ?? $result['ses_api_region'] ) );

		$result['generic_api_endpoint']   = esc_url_raw( $data['generic_api_endpoint'] ?? ( $current['generic_api_endpoint'] ?? $result['generic_api_endpoint'] ) );
		$result['generic_api_method']     = self::sanitize_generic_method( $data['generic_api_method'] ?? ( $current['generic_api_method'] ?? $result['generic_api_method'] ) );
		$result['generic_api_auth_token'] = trim( (string) ( $data['generic_api_auth_token'] ?? ( $current['generic_api_auth_token'] ?? $result['generic_api_auth_token'] ) ) );

		return $result;
	}

	/**
	 * Sanitize SES region string.
	 *
	 * @param string $region Raw region string.
	 * @return string
	 */
	private static function sanitize_ses_region( string $region ): string {
		$region  = strtolower( sanitize_text_field( $region ) );
		$allowed = array(
			'us-east-1',
			'us-east-2',
			'us-west-2',
			'ca-central-1',
			'eu-west-1',
			'eu-west-2',
			'eu-central-1',
			'eu-central-2',
			'ap-south-1',
			'ap-southeast-1',
			'ap-southeast-2',
			'ap-northeast-1',
			'ap-northeast-2',
			'sa-east-1',
		);

		return in_array( $region, $allowed, true ) ? $region : 'us-east-1';
	}

	/**
	 * Sanitize HTTP method for generic HTTP transport.
	 *
	 * @param string $method Raw method.
	 * @return string
	 */
	private static function sanitize_generic_method( string $method ): string {
		$method = strtoupper( sanitize_text_field( $method ) );

		return in_array( $method, array( 'POST', 'PUT' ), true ) ? $method : 'POST';
	}
}
