<?php
/**
 * A class that sends email through Sparkpost.
 *
 * @since 3.0.0
 */

declare( strict_types=1 );
namespace FeData\FastEvents\Mail\Provider;

use Exception;
use FeData\FastEvents\Mail\AbstractMailer;
use FeData\FastEvents\Utilities\JsonUtil;
use FeData\FastEvents\Utilities\PluginUtil;
use stdClass;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

defined( 'ABSPATH' ) || exit;

/**
 * A class that sends email through Sparkpost.
 */
final class SparkpostMailer extends AbstractMailer {

	/**
	 * Send mail using the Sparkpost API.
	 *
	 * @since 1.0
	 * @since 1.9 Added event_id and order_id to the message.
	 * @since 2.5.0 Set provider id.
	 *
	 * @param stdClass $order   Order information.
	 * @param string   $bcc     Emailaddress of BBC receiver.
	 * @param string   $subject Subject of the email.
	 * @param string   $msg     HTML mail message.
	 * @param int      $em_type 0=Normal mail, 1=Confirmation email.
	 * @throws Exception If mail can't be sent.
	 */
	protected function provider_send( stdClass $order, string $bcc, string $subject, string $msg, int $em_type ): void {
		$this->provider_id = 'sparkpost';

		// Recipients.
		$rcpts[] = array( 'address' => $order->email );

		// Is there a BCC?
		if ( ! empty( $bcc ) ) {
			$rcpts[] = array( 'address' => $bcc );
		}

		// Message.
		$data                       = new stdClass();
		$data->recipients           = $rcpts;
		$data->content              = new stdClass();
		$data->content->from        = new stdClass();
		$data->content->from->name  = $this->get_sender_name( $order );
		$data->content->from->email = $this->get_sender_email( $order );
		$data->content->subject     = $subject;
		$data->content->html        = $msg;
		$data->content->text        = wp_strip_all_tags( $msg );

		// Send the message.
		$response = wp_safe_remote_post(
			$this->settings->mailer_property( 'server' ),
			array(
				'user-agent' => PluginUtil::get_user_agent(),
				'timeout'    => self::CONNECTION_TIMEOUT,
				'headers'    => array(
					'Accept'        => 'application/json',
					'Authorization' => $this->settings->mailer_property( 'api_key' ),
					'Content-Type'  => 'application/json',
				),
				'body'       => JsonUtil::fast_events_json_encode( $data ),
			)
		);

		// Check for errors.
		$this->check_email_provider_api_error( $response, $order, $em_type );
	}

	/**
	 * Extract the email_id used by Sparkpost.
	 *
	 * @since 2.5.0
	 *
	 * @param array|WP_Error $response API response from provider.
	 */
	protected function set_email_id( WP_Error|array $response ): void {
		$json           = json_decode( wp_remote_retrieve_body( $response ) );
		$this->email_id = $json->results->id;
	}

	/**
	 * Process the Sparkpost webhook events.
	 *
	 * @since 2.4.0
	 * @since 2.5.0 All events are added to the email log, and error events are added to the errorlog as well.
	 *
	 * @param WP_REST_Request $data Request instance.
	 *
	 * @return WP_REST_Response | WP_Error
	 */
	public function webhook( WP_REST_Request $data ): WP_Error|WP_REST_Response {
		$this->provider_id = 'sparkpost';
		return new WP_Error( 'not_implemented', __( 'This Sparkpost implementation does not support webhooks.', 'fast-events' ) );
	}
}
