<?php
/**
 * @package Hafenstudios\Kurato
 */

namespace Hafenstudios\Kurato\Mail;

use Hafenstudios\Core\Mail\Message;

defined( 'ABSPATH' ) || exit;

/**
 * Amazon-SES-Versandtreiber (SES v2 API, SendEmail/Simple).
 *
 * Guenstigster Massenversand, aber AWS Signature v4 statt API-Key (siehe
 * AwsV4Signer). Region bestimmt Endpunkt und Datenstandort (z.B. eu-central-1).
 */
final class SesDriver extends AbstractApiEspDriver {

	private string $access_key;

	private string $secret_key;

	private string $region;

	/**
	 * @param string $access_key AWS Access Key ID.
	 * @param string $secret_key AWS Secret Access Key.
	 * @param string $region     Region (z.B. eu-central-1).
	 */
	public function __construct( string $access_key, string $secret_key, string $region ) {
		$this->access_key = $access_key;
		$this->secret_key = $secret_key;
		$this->region     = $region;
	}

	/**
	 * @return string
	 */
	public function key(): string {
		return 'ses';
	}

	/**
	 * @return string
	 */
	protected function endpoint(): string {
		return 'https://' . $this->host() . '/v2/email/outbound-emails';
	}

	/**
	 * @return bool
	 */
	protected function is_configured(): bool {
		return '' !== $this->access_key && '' !== $this->secret_key && '' !== $this->region;
	}

	/**
	 * @return string
	 */
	protected function config_error(): string {
		return __( 'AWS-Zugangsdaten oder Region fuer SES fehlen.', 'kurato' );
	}

	/**
	 * @param Message $message Nachricht.
	 * @return array{headers:array<string,string>,body:string}
	 */
	protected function build_request( Message $message ): array {
		$from = '' !== $message->from_name
			? sprintf( '%s <%s>', $message->from_name, $message->from_email )
			: $message->from_email;

		if ( $message->is_html ) {
			$mail_body = array( 'Html' => array( 'Data' => $message->body, 'Charset' => 'UTF-8' ) );
			// Multipart: Klartext-Alternative als Text-Teil neben dem Html-Teil (SES).
			if ( '' !== $message->text_body ) {
				$mail_body['Text'] = array( 'Data' => $message->text_body, 'Charset' => 'UTF-8' );
			}
		} else {
			$mail_body = array( 'Text' => array( 'Data' => $message->body, 'Charset' => 'UTF-8' ) );
		}

		$content = array(
			'Subject' => array( 'Data' => $message->subject, 'Charset' => 'UTF-8' ),
			'Body'    => $mail_body,
		);
		if ( array() !== $message->headers ) {
			$headers = array();
			foreach ( $message->headers as $name => $value ) {
				$headers[] = array( 'Name' => $name, 'Value' => $value );
			}
			$content['Headers'] = $headers;
		}

		$body = array(
			'FromEmailAddress' => $from,
			'Destination'      => array( 'ToAddresses' => array( $message->to ) ),
			'Content'          => array( 'Simple' => $content ),
		);
		if ( '' !== $message->reply_to ) {
			$body['ReplyToAddresses'] = array( $message->reply_to );
		}

		$payload = (string) wp_json_encode( $body );
		$signed  = ( new AwsV4Signer( $this->access_key, $this->secret_key, $this->region ) )
			->sign_post( $this->host(), '/v2/email/outbound-emails', $payload );

		return array(
			'headers' => array(
				'Authorization' => $signed['Authorization'],
				'X-Amz-Date'    => $signed['X-Amz-Date'],
				'Content-Type'  => $signed['Content-Type'],
			),
			'body'    => $payload,
		);
	}

	/**
	 * @param string $body Response-Body.
	 * @return string
	 */
	protected function parse_message_id( string $body ): string {
		return $this->json_value( $body, 'MessageId' );
	}

	/**
	 * SES-Host der Region.
	 *
	 * @return string
	 */
	private function host(): string {
		return 'email.' . $this->region . '.amazonaws.com';
	}
}
