<?php
/**
 * Email sender.
 *
 * @package CartNinjaRecovery
 */

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

class CARTNINJA_Email_Sender {

	public function send_cart_email( $cart, $context = array() ) {
		$to = isset( $cart['email'] ) ? sanitize_email( $cart['email'] ) : '';

		if ( empty( $to ) || ! is_email( $to ) ) {
			return array(
				'status'             => 'failed',
				'error_message'      => __( 'Customer email address is missing or invalid.', 'cartninja-recovery-for-woocommerce' ),
				'gateway_message_id' => '',
				'message'            => '',
			);
		}

		$context = wp_parse_args(
			$context,
			array(
				'customer_name' => __( 'there', 'cartninja-recovery-for-woocommerce' ),
				'cart_total'    => function_exists( 'wc_price' ) ? wp_strip_all_tags( wc_price( (float) $cart['cart_total'] ) ) : number_format_i18n( (float) $cart['cart_total'], 2 ),
				'cart_url'      => $this->build_recovery_url( $cart ),
				'site_name'     => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ),
				'coupon_code'   => isset( $cart['coupon_code'] ) ? sanitize_text_field( $cart['coupon_code'] ) : '',
				'email_subject' => '',
				'email_heading' => '',
				'email_template'=> '',
				'email_button_text' => '',
				'email_footer_text' => '',
			)
		);
		$context['cart']       = $cart;
		$context['cart_items'] = $this->prepare_cart_items( $cart );

		$subject = $this->render_subject( $context );
		$body    = $this->render_body( $context );
		$headers = array( 'Content-Type: text/html; charset=UTF-8' );
		$mail_error = null;
		$capture_mail_error = static function ( $error ) use ( &$mail_error ) {
			if ( is_wp_error( $error ) ) {
				$mail_error = $error;
			}
		};

		add_action( 'wp_mail_failed', $capture_mail_error );

		try {
			$sent = function_exists( 'WC' ) && WC()->mailer() ? WC()->mailer()->send( $to, $subject, $body, $headers ) : wp_mail( $to, $subject, $body, $headers );
		} catch ( Throwable $exception ) {
			$sent       = false;
			$mail_error = new WP_Error( 'cartninja_mail_exception', $exception->getMessage() );
		} finally {
			remove_action( 'wp_mail_failed', $capture_mail_error );
		}

		$error_message = '';
		if ( ! $sent ) {
			$error_message = $mail_error instanceof WP_Error && $mail_error->get_error_message()
				? sanitize_text_field( $mail_error->get_error_message() )
				: __( 'The site mailer failed to accept the reminder email.', 'cartninja-recovery-for-woocommerce' );
		}

		return array(
			'status'             => $sent ? 'sent' : 'failed',
			'error_message'      => $error_message,
			'gateway_message_id' => '',
			'message'            => $body,
		);
	}

	public function render_subject( $context ) {
		$settings = get_option( 'cartninja_settings', array() );
		$subject  = ! empty( $context['email_subject'] ) ? $context['email_subject'] : ( isset( $settings['message']['email_subject'] ) ? $settings['message']['email_subject'] : __( 'Complete your purchase at {{site_name}}', 'cartninja-recovery-for-woocommerce' ) );

		return $this->replace_tokens( $subject, $context );
	}

	public function render_body( $context ) {
		$settings = get_option( 'cartninja_settings', array() );
		$message  = ! empty( $context['email_template'] ) ? $context['email_template'] : ( isset( $settings['message']['email_template'] ) ? $settings['message']['email_template'] : __( "Hi {{customer_name}},\n\nYou left items worth {{cart_total}} in your cart at {{site_name}}.\n\nResume your checkout here:\n{{cart_url}}", 'cartninja-recovery-for-woocommerce' ) );
		$heading  = ! empty( $context['email_heading'] ) ? $context['email_heading'] : ( isset( $settings['message']['email_heading'] ) ? $settings['message']['email_heading'] : __( 'You left something behind', 'cartninja-recovery-for-woocommerce' ) );
		$button   = ! empty( $context['email_button_text'] ) ? $context['email_button_text'] : ( isset( $settings['message']['email_button_text'] ) ? $settings['message']['email_button_text'] : __( 'Resume your checkout', 'cartninja-recovery-for-woocommerce' ) );
		$footer   = ! empty( $context['email_footer_text'] ) ? $context['email_footer_text'] : ( isset( $settings['message']['email_footer_text'] ) ? $settings['message']['email_footer_text'] : '' );
		$message  = $this->replace_tokens( $message, $context );
		$heading  = $this->replace_tokens( $heading, $context );
		$button   = $this->replace_tokens( $button, $context );
		$footer   = $this->replace_tokens( $footer, $context );

		if ( function_exists( 'wc_get_template_html' ) ) {
			return wc_get_template_html(
				'emails/cartninja-abandoned-cart.php',
				array(
					'cart'              => isset( $context['cart'] ) ? $context['cart'] : array(),
					'cart_items'        => isset( $context['cart_items'] ) ? $context['cart_items'] : array(),
					'cart_total'        => isset( $context['cart_total'] ) ? sanitize_text_field( $context['cart_total'] ) : '',
					'cart_url'          => isset( $context['cart_url'] ) ? esc_url_raw( $context['cart_url'] ) : '',
					'coupon_code'       => isset( $context['coupon_code'] ) ? sanitize_text_field( $context['coupon_code'] ) : '',
					'customer_name'     => isset( $context['customer_name'] ) ? sanitize_text_field( $context['customer_name'] ) : '',
					'email_heading'     => $heading,
					'message'           => $message,
					'button_text'       => $button,
					'additional_content'=> $footer,
					'plain_text'        => false,
					'email'             => null,
				),
				'cartninja/',
				CARTNINJA_PLUGIN_DIR . 'templates/'
			);
		}

		return wpautop( wp_kses_post( $message ) );
	}

	private function replace_tokens( $content, $context ) {
		return strtr(
			(string) $content,
			array(
				'{{customer_name}}' => sanitize_text_field( $context['customer_name'] ),
				'{{cart_total}}'    => sanitize_text_field( $context['cart_total'] ),
				'{{cart_url}}'      => esc_url_raw( $context['cart_url'] ),
				'{{site_name}}'     => sanitize_text_field( $context['site_name'] ),
				'{{coupon_code}}'   => sanitize_text_field( $context['coupon_code'] ),
			)
		);
	}

	private function build_recovery_url( $cart ) {
		$settings = get_option( 'cartninja_settings', array() );
		$general  = isset( $settings['general'] ) ? $settings['general'] : array();
		$base_url = ! empty( $general['recovery_url_base'] ) ? $general['recovery_url_base'] : home_url( '/cart/' );

		return add_query_arg( 'cartninja_token', sanitize_text_field( $cart['recovery_token'] ), $base_url );
	}

	private function prepare_cart_items( $cart ) {
		$items    = array();
		$contents = isset( $cart['cart_contents'] ) ? json_decode( $cart['cart_contents'], true ) : array();
		$currency = isset( $cart['currency'] ) ? sanitize_text_field( $cart['currency'] ) : '';

		if ( ! is_array( $contents ) ) {
			return $items;
		}

		foreach ( $contents as $item ) {
			if ( ! is_array( $item ) ) {
				continue;
			}

			$product_id   = isset( $item['product_id'] ) ? absint( $item['product_id'] ) : 0;
			$variation_id = isset( $item['variation_id'] ) ? absint( $item['variation_id'] ) : 0;
			$quantity     = isset( $item['quantity'] ) ? max( 1, absint( $item['quantity'] ) ) : 1;
			$line_total   = isset( $item['line_total'] ) ? (float) $item['line_total'] : 0;
			$product      = function_exists( 'wc_get_product' ) ? wc_get_product( $variation_id ? $variation_id : $product_id ) : false;
			$name         = $product ? $product->get_name() : ( isset( $item['product_name'] ) ? sanitize_text_field( $item['product_name'] ) : __( 'Product', 'cartninja-recovery-for-woocommerce' ) );

			$items[] = array(
				'product_id'   => $product_id,
				'variation_id' => $variation_id,
				'name'         => $name,
				'quantity'     => $quantity,
				'variation'    => isset( $item['variation'] ) && is_array( $item['variation'] ) ? $this->format_variation( $item['variation'] ) : '',
				'image'        => $product ? $product->get_image( array( 48, 48 ) ) : '',
				'line_total'   => $this->format_money( $line_total, $currency ),
			);
		}

		return $items;
	}

	private function format_variation( $variation ) {
		$parts = array();

		foreach ( $variation as $attribute => $value ) {
			$value = sanitize_text_field( (string) $value );
			if ( '' === $value ) {
				continue;
			}

			$label   = function_exists( 'wc_attribute_label' ) ? wc_attribute_label( str_replace( 'attribute_', '', (string) $attribute ) ) : $attribute;
			$parts[] = sprintf( '%s: %s', $label, $value );
		}

		return implode( ', ', $parts );
	}

	private function format_money( $amount, $currency ) {
		if ( function_exists( 'wc_price' ) ) {
			$args = array();
			if ( $currency ) {
				$args['currency'] = $currency;
			}

			return wc_price( (float) $amount, $args );
		}

		return esc_html( number_format_i18n( (float) $amount, 2 ) );
	}
}
