<?php
/**
 * Shared TutorHelper email sender.
 *
 * @package TutorHelper_Bookings
 */

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

/**
 * Sends registered TutorHelper email templates.
 */
final class TutorHelper_Email_Sender {

	/**
	 * Send one registered TutorHelper email.
	 *
	 * @param string $template_key   Template identifier.
	 * @param string $recipient      Recipient email address.
	 * @param array  $placeholders   Placeholder/value map.
	 * @param array  $args           Optional sending arguments.
	 *
	 * @return true|WP_Error
	 */
	public static function send(
		$template_key,
		$recipient,
		$placeholders = array(),
		$args = array()
	) {
		$template_key =
			sanitize_key(
				$template_key
			);

		$recipient =
			sanitize_email(
				$recipient
			);

		$template =
			TutorHelper_Email_Templates::get(
				$template_key
			);

		if ( ! $template ) {
			return new WP_Error(
				'tutorhelper_email_template_missing',
				__(
					'The requested email template could not be found.',
					'tutorhelper-bookings'
				)
			);
		}

		if (
			empty(
				$template[
					'enabled'
				]
			)
		) {
			return new WP_Error(
				'tutorhelper_email_template_disabled',
				__(
					'This email template is disabled.',
					'tutorhelper-bookings'
				)
			);
		}

		if (
			'' === $recipient
			|| ! is_email(
				$recipient
			)
		) {
			return new WP_Error(
				'tutorhelper_email_recipient_invalid',
				__(
					'The email recipient is missing or invalid.',
					'tutorhelper-bookings'
				)
			);
		}

		$args =
			wp_parse_args(
				is_array( $args )
					? $args
					: array(),
				array(
					'reply_to_email' =>
						'',

					'reply_to_name' =>
						'',

					'headers' =>
						array(),

					'context' =>
						array(),
				)
			);

		$rendered =
			TutorHelper_Email_Renderer::render(
				$template_key,
				$placeholders
			);

		if ( is_wp_error( $rendered ) ) {
			return $rendered;
		}

		$headers = array(
			'Content-Type: text/html; charset=UTF-8',
		);

		$reply_to_email =
			sanitize_email(
				$args[
					'reply_to_email'
				]
			);

		$reply_to_name =
			sanitize_text_field(
				$args[
					'reply_to_name'
				]
			);

		if (
			$reply_to_email
			&& is_email(
				$reply_to_email
			)
		) {
			if ( '' === $reply_to_name ) {
				$reply_to_name =
					wp_specialchars_decode(
						get_bloginfo(
							'name'
						),
						ENT_QUOTES
					);
			}

			$headers[] =
				'Reply-To: '
				. $reply_to_name
				. ' <'
				. $reply_to_email
				. '>';
		}

		if (
			is_array(
				$args['headers']
			)
		) {
			foreach (
				$args['headers']
				as $header
			) {
				$header =
					trim(
						(string) $header
					);

				if ( '' !== $header ) {
					$headers[] =
						$header;
				}
			}
		}

		/**
		 * Filters TutorHelper email headers before sending.
		 *
		 * @param array  $headers      Mail headers.
		 * @param string $template_key Template identifier.
		 * @param string $recipient    Recipient email.
		 * @param array  $args         Sending arguments.
		 */
		$headers =
			apply_filters(
				'tutorhelper_email_headers',
				$headers,
				$template_key,
				$recipient,
				$args
			);

		$sent =
			wp_mail(
				$recipient,
				$rendered[
					'subject'
				],
				$rendered[
					'html'
				],
				$headers
			);

		$context =
			is_array(
				$args['context']
			)
				? $args['context']
				: array();

		$context[
			'template_key'
		] =
			$template_key;

		$context[
			'recipient'
		] =
			$recipient;

		if ( ! $sent ) {
			if (
				class_exists(
					'TutorHelper_Logger'
				)
				&& method_exists(
					'TutorHelper_Logger',
					'error'
				)
			) {
				TutorHelper_Logger::error(
					'TutorHelper email failed to send.',
					$context
				);
			}

			/**
			 * Fires after wp_mail() fails.
			 *
			 * @param string $template_key Template identifier.
			 * @param string $recipient    Recipient email.
			 * @param array  $context      Sending context.
			 */
			do_action(
				'tutorhelper_email_failed',
				$template_key,
				$recipient,
				$context
			);

			return new WP_Error(
				'tutorhelper_email_send_failed',
				__(
					'The email could not be sent.',
					'tutorhelper-bookings'
				)
			);
		}

		if (
			class_exists(
				'TutorHelper_Logger'
			)
			&& method_exists(
				'TutorHelper_Logger',
				'success'
			)
		) {
			TutorHelper_Logger::success(
				'TutorHelper email sent.',
				$context
			);
		}

		/**
		 * Fires after a TutorHelper email is sent.
		 *
		 * @param string $template_key Template identifier.
		 * @param string $recipient    Recipient email.
		 * @param array  $context      Sending context.
		 */
		do_action(
			'tutorhelper_email_sent',
			$template_key,
			$recipient,
			$context
		);

		return true;
	}
}
