<?php
/**
 * Custom email destination.
 *
 * @package Ordsync
 */

defined( 'ABSPATH' ) || exit;

/**
 * Sends a custom email when an order reaches the chosen status.
 * Supports {variables} in the subject and the body.
 */
class Ordsync_Dest_Email extends Ordsync_Destination {

	/**
	 * Key.
	 *
	 * @return string
	 */
	public function key() {
		return 'email';
	}

	/**
	 * Label.
	 *
	 * @return string
	 */
	public function label() {
		return __( 'Custom Email', 'ordercarry-order-automation-for-woocommerce' );
	}

	/**
	 * Enabled and configured.
	 *
	 * @return bool
	 */
	public function is_enabled() {
		return parent::is_enabled() && '' !== $this->setting( 'to' );
	}

	/**
	 * The variables a user may use.
	 *
	 * @return array
	 */
	public static function variables() {
		return array(
			'{order_number}',
			'{status}',
			'{date}',
			'{customer_name}',
			'{customer_email}',
			'{customer_phone}',
			'{items}',
			'{total}',
			'{currency}',
			'{store_name}',
			'{coupons}',
			'{shipping_method}',
			'{transaction_id}',
			'{order_note}',
		);
	}

	/**
	 * Send.
	 *
	 * @param array $payload Order payload.
	 * @return true|WP_Error
	 */
	public function send( array $payload ) {

		$to = $this->resolve_recipient( $this->setting( 'to' ), $payload );

		if ( ! is_email( $to ) ) {
			return new WP_Error(
				'ordsync_bad_email',
				sprintf(
					/* translators: %s: the recipient value that failed validation */
					__( 'Not a valid recipient address: %s', 'ordercarry-order-automation-for-woocommerce' ),
					$to
				),
				array( 'status' => 400 )
			);
		}

		$subject = $this->replace( $this->setting( 'subject' ), $payload );
		$body    = $this->replace( $this->setting( 'body' ), $payload );

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

		$sent = wp_mail( $to, $subject, wpautop( $body ), $headers );

		if ( ! $sent ) {
			return new WP_Error(
				'ordsync_mail_failed',
				__( 'Your server refused to send the email. This is almost always a hosting problem, not a plugin problem — install a free SMTP plugin to fix it.', 'ordercarry-order-automation-for-woocommerce' ),
				array( 'status' => 0 )
			);
		}

		return true;
	}

	/**
	 * Allow "customer" as a magic recipient.
	 *
	 * @param string $to      Configured recipient.
	 * @param array  $payload Payload.
	 * @return string
	 */
	private function resolve_recipient( $to, array $payload ) {
		if ( 'customer' === strtolower( trim( $to ) ) ) {
			return isset( $payload['customer']['email'] ) ? $payload['customer']['email'] : '';
		}
		return trim( $to );
	}

	/**
	 * Swap {variables} for real values.
	 *
	 * @param string $text    Raw text.
	 * @param array  $payload Payload.
	 * @return string
	 */
	private function replace( $text, array $payload ) {

		$customer = isset( $payload['customer'] ) ? $payload['customer'] : array();

		$name = trim(
			( isset( $customer['first_name'] ) ? $customer['first_name'] : '' ) . ' ' .
			( isset( $customer['last_name'] ) ? $customer['last_name'] : '' )
		);

		$items = array();
		foreach ( ( isset( $payload['items'] ) ? $payload['items'] : array() ) as $item ) {
			$items[] = $item['quantity'] . '× ' . $item['name'];
		}

		$map = array(
			'{order_number}'   => isset( $payload['order_number'] ) ? $payload['order_number'] : '',
			'{status}'         => isset( $payload['status'] ) ? $payload['status'] : '',
			'{date}'           => isset( $payload['date'] ) ? $payload['date'] : '',
			'{customer_name}'  => $name,
			'{customer_email}' => isset( $customer['email'] ) ? $customer['email'] : '',
			'{customer_phone}' => isset( $customer['phone'] ) ? $customer['phone'] : '',
			'{items}'          => implode( ', ', $items ),
			'{total}'          => isset( $payload['total'] ) ? $payload['total'] : '',
			'{currency}'       => isset( $payload['currency'] ) ? $payload['currency'] : '',
			'{store_name}'     => isset( $payload['store']['name'] ) ? $payload['store']['name'] : '',
			'{coupons}'        => isset( $payload['coupons_text'] ) ? $payload['coupons_text'] : '',
			'{shipping_method}' => isset( $payload['shipping_method'] ) ? $payload['shipping_method'] : '',
			'{transaction_id}' => isset( $payload['transaction_id'] ) ? $payload['transaction_id'] : '',
			'{order_note}'     => isset( $payload['note'] ) ? $payload['note'] : '',
		);

		return str_replace( array_keys( $map ), array_values( $map ), (string) $text );
	}
}
