<?php
/**
 * Resend email API provider.
 *
 * @package EmailSmtp
 * @link https://resend.com/docs/api-reference/introduction
 * @link https://resend.com/docs/api-reference/emails/send-email
 */

namespace EmailSmtp\Providers\Resend;

use EmailSmtp\Includes\AbstractApiProvider;
use EmailSmtp\Includes\ApiHttpClient;
use EmailSmtp\Includes\DeliveryResult;
use EmailSmtp\Includes\EmailMessage;
use EmailSmtp\Includes\ErrorNormalizer;

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

final class Provider extends AbstractApiProvider {

	/** Max addresses per to/cc/bcc on POST /emails. */
	private const RECIPIENT_CAP = 50;

	public function get_id(): string {
		return 'resend';
	}

	public function get_name(): string {
		return __( 'Resend', 'wp-powersuite' );
	}

	public function get_description(): string {
		return __( 'Send transactional email through the Resend REST API.', 'wp-powersuite' );
	}

	public function get_recommended_use(): string {
		return __( 'Developer-friendly transactional delivery.', 'wp-powersuite' );
	}

	public function get_docs_url(): string {
		return 'https://resend.com/docs/api-reference/emails/send-email';
	}

	public function get_icon(): string {
		return 'dashicons-email';
	}

	public function get_required_fields(): array {
		return [ 'resend_api_key' ];
	}


	/**
	 * @param array<string, mixed> $settings
	 * @return array<string, string>
	 */
	private function auth_headers( array $settings, bool $idempotent = false ): array {
		$key = $this->secret( $settings, 'resend_api_key', 'WP_POWERSUITE_RESEND_API_KEY' );
		$headers = [
			'Authorization' => 'Bearer ' . $key,
			'Content-Type'  => 'application/json',
		];
		if ( $idempotent ) {
			$headers['Idempotency-Key'] = wp_generate_uuid4();
		}
		return $headers;
	}

	public function connect( array $settings ): DeliveryResult {
		$key = $this->secret( $settings, 'resend_api_key', 'WP_POWERSUITE_RESEND_API_KEY' );
		if ( $key === '' ) {
			return DeliveryResult::failure( __( 'Resend API key is required.', 'wp-powersuite' ), '', 'authentication' );
		}

		// List domains needs Full access; sending-only keys return restricted_api_key.
		$response = ApiHttpClient::request(
			'GET',
			'https://api.resend.com/domains',
			$this->auth_headers( $settings )
		);

		if ( ! empty( $response['error'] ) ) {
			return ErrorNormalizer::from_text( (string) $response['error'] );
		}

		$code = (int) ( $response['code'] ?? 0 );
		$json = is_array( $response['json'] ?? null ) ? $response['json'] : [];
		$name = is_string( $json['name'] ?? null ) ? (string) $json['name'] : '';

		if ( $code === 401 && $name === 'restricted_api_key' ) {
			return DeliveryResult::success(
				__( 'Resend API key accepted (sending access only). Full access is required to list domains.', 'wp-powersuite' )
			);
		}

		return ApiHttpClient::to_delivery_result(
			$response,
			static function () {
				return [ 'message' => __( 'Resend API key authenticated successfully.', 'wp-powersuite' ) ];
			}
		);
	}

	public function send( EmailMessage $message, array $settings ): DeliveryResult {
		$missing = $this->require_from( $message );
		if ( $missing ) {
			return $missing;
		}

		$key = $this->secret( $settings, 'resend_api_key', 'WP_POWERSUITE_RESEND_API_KEY' );
		if ( $key === '' ) {
			return DeliveryResult::failure( __( 'Resend API key is required.', 'wp-powersuite' ), '', 'authentication' );
		}

		$from    = $this->from_parts( $message );
		$payload = [
			'from'    => $this->format_address( $from['email'], $from['name'] ),
			'to'      => array_slice( $message->get_to(), 0, self::RECIPIENT_CAP ),
			'subject' => $message->get_subject(),
		];

		if ( $message->is_html() ) {
			$payload['html'] = $message->get_body();
			// Resend can derive text from HTML; we still send an explicit fallback when available.
			if ( $message->get_alt_body() !== '' ) {
				$payload['text'] = $message->get_alt_body();
			}
		} else {
			$payload['text'] = $message->get_body();
		}

		if ( $message->get_cc() !== [] ) {
			$payload['cc'] = array_slice( $message->get_cc(), 0, self::RECIPIENT_CAP );
		}
		if ( $message->get_bcc() !== [] ) {
			$payload['bcc'] = array_slice( $message->get_bcc(), 0, self::RECIPIENT_CAP );
		}
		if ( is_email( $message->get_reply_to_email() ) ) {
			$payload['reply_to'] = $this->format_address(
				$message->get_reply_to_email(),
				$message->get_reply_to_name()
			);
		}

		$headers = $this->safe_custom_headers( $message );
		if ( $headers !== [] ) {
			$payload['headers'] = $headers;
		}

		$attachments = $this->attachments_as_base64( $message );
		if ( $attachments !== [] ) {
			$payload['attachments'] = array_map(
				static function ( array $a ) {
					$row = [
						'filename' => $a['name'],
						'content'  => $a['content'],
					];
					if ( $a['type'] !== '' ) {
						$row['content_type'] = $a['type'];
					}
					return $row;
				},
				$attachments
			);
		}

		$response = ApiHttpClient::request(
			'POST',
			'https://api.resend.com/emails',
			$this->auth_headers( $settings, true ),
			$payload
		);

		return ApiHttpClient::to_delivery_result(
			$response,
			static function ( array $res ) {
				$id = is_array( $res['json'] ) ? (string) ( $res['json']['id'] ?? '' ) : '';
				return [
					'message' => __( 'Resend accepted the message.', 'wp-powersuite' ),
					'id'      => $id,
				];
			}
		);
	}
}
