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

namespace Hafenstudios\Kurato\Mail;

use Hafenstudios\Core\Mail\Message;

defined( 'ABSPATH' ) || exit;

/**
 * Mailgun-Versandtreiber. Basic-Auth (api:key), form-kodierter Body und die
 * Sende-Domain in der URL; EU-Region waehlbar (Datenstandort).
 */
final class MailgunDriver extends AbstractApiEspDriver {

	private string $api_key;

	private string $domain;

	private string $region;

	/**
	 * @param string $api_key Mailgun-API-Key.
	 * @param string $domain  Sende-Domain (z.B. mg.example.com).
	 * @param string $region  "eu" fuer die EU-Region, sonst US.
	 */
	public function __construct( string $api_key, string $domain, string $region = 'us' ) {
		$this->api_key = $api_key;
		$this->domain  = $domain;
		$this->region  = 'eu' === strtolower( $region ) ? 'eu' : 'us';
	}

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

	/**
	 * @return string
	 */
	protected function endpoint(): string {
		$host = 'eu' === $this->region ? 'api.eu.mailgun.net' : 'api.mailgun.net';
		return 'https://' . $host . '/v3/' . rawurlencode( $this->domain ) . '/messages';
	}

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

	/**
	 * @return string
	 */
	protected function config_error(): string {
		return __( 'Mailgun-API-Key oder Sende-Domain fehlt.', '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;

		$fields = array(
			'from'    => $from,
			'to'      => $message->to,
			'subject' => $message->subject,
		);
		if ( $message->is_html ) {
			$fields['html'] = $message->body;
			// Multipart: Klartext-Alternative als text-Feld mitsenden (Mailgun).
			if ( '' !== $message->text_body ) {
				$fields['text'] = $message->text_body;
			}
		} else {
			$fields['text'] = $message->body;
		}
		if ( '' !== $message->reply_to ) {
			$fields['h:Reply-To'] = $message->reply_to;
		}
		foreach ( $message->headers as $name => $value ) {
			$fields[ 'h:' . $name ] = $value;
		}

		return array(
			'headers' => array(
				'Authorization' => 'Basic ' . base64_encode( 'api:' . $this->api_key ),
				'Content-Type'  => 'application/x-www-form-urlencoded',
			),
			'body'    => http_build_query( $fields ),
		);
	}

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