<?php
/**
 * Brevo transactional email resource.
 *
 * @package RewindBrevoFormBridge
 */

namespace RewindBrevoFormBridge\Api;

use RewindBrevoFormBridge\Support\Errors;

defined( 'ABSPATH' ) || exit;

/**
 * POST /smtp/email and GET /senders.
 *
 * This is what makes a separate WP SMTP plugin unnecessary: wp_mail() is
 * short-circuited into this endpoint using the same account-wide v3 API
 * key, over HTTPS 443, so no SMTP port has to be open.
 *
 * @since 0.5.0
 */
class Transactional {

	/**
	 * API client.
	 *
	 * @var Client
	 */
	private Client $client;

	/**
	 * Transient cache.
	 *
	 * @var Cache
	 */
	private Cache $cache;

	/**
	 * Constructor.
	 *
	 * @since 0.5.0
	 * @param Client $client API client.
	 * @param Cache  $cache  Transient cache.
	 */
	public function __construct( Client $client, Cache $cache ) {
		$this->client = $client;
		$this->cache  = $cache;
	}

	/**
	 * Send one transactional email.
	 *
	 * @since 0.5.0
	 * @param array $payload /smtp/email body: sender, to, subject,
	 *                       htmlContent|textContent, and optionally cc, bcc,
	 *                       replyTo, attachment, headers.
	 * @return Response 201 with { messageId } on success.
	 */
	public function send( array $payload ): Response {
		return $this->client->post( '/smtp/email', $payload );
	}

	/**
	 * Every sender registered on the account.
	 *
	 * Brevo refuses a send whose sender address is not registered and
	 * verified, so the Email settings screen offers these as a picker
	 * rather than letting the owner type an address that will bounce.
	 *
	 * @since 0.5.0
	 * @param bool $force Bypass the cache (explicit refresh only).
	 * @return array|\WP_Error Rows of ['id','name','email','active'].
	 */
	public function senders( bool $force = false ) {
		if ( ! $force ) {
			$cached = $this->cached_senders();

			if ( null !== $cached ) {
				return $cached;
			}
		}

		$response = $this->client->get( '/senders' );

		if ( ! $response->is_success() ) {
			return new \WP_Error( 'rbfb_api_error', Errors::translate( $response ) );
		}

		$body = $response->body();
		$rows = ( isset( $body['senders'] ) && is_array( $body['senders'] ) ) ? $body['senders'] : array();

		$senders = array();
		foreach ( $rows as $row ) {
			if ( ! is_array( $row ) || empty( $row['email'] ) ) {
				continue;
			}

			$senders[] = array(
				'id'     => isset( $row['id'] ) ? (int) $row['id'] : 0,
				'name'   => isset( $row['name'] ) ? (string) $row['name'] : '',
				'email'  => (string) $row['email'],
				// Brevo omits `active` for senders on a verified domain; those
				// are usable, so absent means active rather than blocked.
				'active' => ! isset( $row['active'] ) || (bool) $row['active'],
			);
		}

		$this->cache->set( 'senders', $senders );

		return $senders;
	}

	/**
	 * Cache-only read — never calls the API. For screen renders.
	 *
	 * @since 0.5.0
	 * @return array|null Null when nothing is cached.
	 */
	public function cached_senders(): ?array {
		$cached = $this->cache->get( 'senders' );

		return is_array( $cached ) ? $cached : null;
	}
}
