<?php
/**
 * Abandoned Cart Recovery WooCommerce email.
 *
 * @package Kramar
 * @since   1.0.0
 */

declare( strict_types=1 );

namespace Kramar\Modules\Marketing;

defined( 'ABSPATH' ) || exit;

/**
 * WooCommerce email sent to a logged-in customer when their cart is abandoned.
 *
 * Registered via `woocommerce_email_classes` so it appears in WC → Settings →
 * Emails and is compatible with Kramar's Email Manager block template pipeline.
 *
 * @since 1.0.0
 */
class Email_Abandoned_Cart extends \WC_Email {

	/**
	 * Cart data captured for the current send (used by the block pipeline).
	 *
	 * @since 1.0.0
	 *
	 * @var array<int, array<string, mixed>>
	 */
	private array $kramar_cart_items = [];

	/** @since 1.0.0 @var string */
	private string $kramar_cart_total = '';

	/** @since 1.0.0 @var string */
	private string $kramar_checkout_url = '';

	/** @since 1.0.0 @var string */
	private string $kramar_unsub_link = '';

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->id             = 'kramar_abandoned_cart';
		$this->title          = __( 'Abandoned Cart Recovery', 'kramar' );
		$this->description    = __( 'Sent to logged-in customers who left items in their cart without completing checkout. GDPR-first: logged-in customers only, includes one-click unsubscribe.', 'kramar' );
		$this->customer_email = true;
		$this->template_html  = '';
		$this->template_plain = '';

		parent::__construct();
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_default_subject(): string {
		return __( 'You left something behind', 'kramar' );
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_default_heading(): string {
		return __( 'Your cart is waiting for you', 'kramar' );
	}

	/**
	 * Send the abandoned cart recovery email.
	 *
	 * @since 1.0.0
	 *
	 * @param string               $recipient  Customer email address.
	 * @param array<string, mixed> $cart_data  Compact cart data from the DB row.
	 * @param string               $unsub_link HMAC-signed unsubscribe URL.
	 */
	public function trigger( string $recipient, array $cart_data, string $unsub_link ): void {
		if ( ! $this->is_enabled() || ! is_email( $recipient ) ) {
			return;
		}

		$this->setup_locale();

		$this->recipient = $recipient;

		$cart_items = [];
		$raw        = $cart_data['cart_contents'] ?? '[]';
		if ( is_string( $raw ) ) {
			$decoded = json_decode( $raw, true );
			if ( is_array( $decoded ) ) {
				$cart_items = $decoded;
			}
		}

		// The DB stores the numeric grand total; format it for display. (Legacy
		// non-numeric values, if any, pass through unchanged.)
		$cart_total_raw = (string) ( $cart_data['cart_total'] ?? '' );
		$cart_total     = ( '' !== $cart_total_raw && is_numeric( $cart_total_raw ) )
			? wc_price( (float) $cart_total_raw )
			: $cart_total_raw;

		$checkout_url = wc_get_checkout_url();

		// Stash for the Email Manager block pipeline (kramar_block_context()).
		$this->kramar_cart_items   = $cart_items;
		$this->kramar_cart_total   = $cart_total;
		$this->kramar_checkout_url = $checkout_url;
		$this->kramar_unsub_link   = $unsub_link;

		$content = $this->build_content( $cart_items, $cart_total, $checkout_url, $unsub_link );

		$this->send(
			$recipient,
			$this->get_subject(),
			$content,
			$this->get_headers(),
			$this->get_attachments()
		);

		$this->restore_locale();
	}

	/**
	 * Build the email HTML body.
	 *
	 * @since 1.0.0
	 *
	 * @param array<int, array<string, mixed>> $cart_items   Cart items array.
	 * @param string                           $cart_total   Formatted cart total.
	 * @param string                           $checkout_url URL to the checkout page.
	 * @param string                           $unsub_link   Unsubscribe URL.
	 * @return string HTML content.
	 */
	private function build_content(
		array $cart_items,
		string $cart_total,
		string $checkout_url,
		string $unsub_link
	): string {
		ob_start();

		$email_heading = $this->get_heading();

		wc_get_template(
			'emails/email-header.php',
			[ 'email_heading' => $email_heading ]
		);
		?>
		<p>
			<?php
			printf(
				/* translators: %s: shop name */
				esc_html__( 'Hi there! You left some items in your cart at %s.', 'kramar' ),
				esc_html( get_bloginfo( 'name' ) )
			);
			?>
		</p>

		<?php if ( ! empty( $cart_items ) ) : ?>
		<table cellpadding="0" cellspacing="0" border="0" style="width:100%;border-collapse:collapse;margin:1em 0;">
			<thead>
				<tr>
					<th align="left" style="padding:.5em;border-bottom:1px solid #ddd;"><?php esc_html_e( 'Product', 'kramar' ); ?></th>
					<th align="right" style="padding:.5em;border-bottom:1px solid #ddd;"><?php esc_html_e( 'Qty', 'kramar' ); ?></th>
					<th align="right" style="padding:.5em;border-bottom:1px solid #ddd;"><?php esc_html_e( 'Price', 'kramar' ); ?></th>
				</tr>
			</thead>
			<tbody>
				<?php foreach ( $cart_items as $item ) : ?>
				<tr>
					<td style="padding:.5em;border-bottom:1px solid #eee;">
						<?php if ( ! empty( $item['url'] ) ) : ?>
						<a href="<?php echo esc_url( (string) $item['url'] ); ?>"><?php echo esc_html( (string) ( $item['name'] ?? '' ) ); ?></a>
						<?php else : ?>
						<?php echo esc_html( (string) ( $item['name'] ?? '' ) ); ?>
						<?php endif; ?>
					</td>
					<td align="right" style="padding:.5em;border-bottom:1px solid #eee;">
						<?php echo esc_html( (string) ( $item['quantity'] ?? 1 ) ); ?>
					</td>
					<td align="right" style="padding:.5em;border-bottom:1px solid #eee;">
						<?php echo esc_html( wc_price( (float) ( $item['price'] ?? 0 ) ) ); ?>
					</td>
				</tr>
				<?php endforeach; ?>
			</tbody>
			<?php if ( $cart_total ) : ?>
			<tfoot>
				<tr>
					<td colspan="2" align="right" style="padding:.5em;font-weight:bold;"><?php esc_html_e( 'Cart total:', 'kramar' ); ?></td>
					<td align="right" style="padding:.5em;font-weight:bold;"><?php echo wp_kses_post( $cart_total ); ?></td>
				</tr>
			</tfoot>
			<?php endif; ?>
		</table>
		<?php endif; ?>

		<p>
			<a href="<?php echo esc_url( $checkout_url ); ?>" style="display:inline-block;padding:.75em 1.5em;background:#000;color:#fff;text-decoration:none;border-radius:3px;">
				<?php esc_html_e( 'Complete your purchase', 'kramar' ); ?>
			</a>
		</p>

		<p style="font-size:.85em;color:#777;margin-top:2em;">
			<?php
			printf(
				/* translators: %s: unsubscribe link */
				esc_html__( 'You are receiving this because you are a registered customer and left items in your cart. %s', 'kramar' ),
				'<a href="' . esc_url( $unsub_link ) . '">' . esc_html__( 'Unsubscribe from cart recovery emails', 'kramar' ) . '</a>'
			);
			?>
		</p>
		<?php

		wc_get_template( 'emails/email-footer.php' );

		return (string) ob_get_clean();
	}

	/**
	 * Provide the merge + items context for Kramar's Email Manager block pipeline.
	 *
	 * Lets the abandoned-cart email be designed in the visual builder using
	 * an Items Table block plus {checkout_url}, {cart_total} and
	 * {unsubscribe_url} merge fields. When the Email Manager is inactive the
	 * hardcoded build_content() fallback is used instead.
	 *
	 * @since 1.0.0
	 *
	 * @return array<string, mixed> Data context: [ 'merge' => [...], 'items' => [...], 'items_total' => string ].
	 */
	public function kramar_block_context(): array {
		$items = [];
		foreach ( $this->kramar_cart_items as $item ) {
			$qty   = (float) ( $item['quantity'] ?? 1 );
			$price = (float) ( $item['price'] ?? 0 );
			$items[] = [
				'name'  => (string) ( $item['name'] ?? '' ),
				'qty'   => (string) ( $item['quantity'] ?? 1 ),
				'total' => wp_strip_all_tags( wc_price( $price * $qty ) ),
			];
		}

		return [
			'merge' => [
				'{checkout_url}'    => $this->kramar_checkout_url,
				'{cart_total}'      => $this->kramar_cart_total,
				'{unsubscribe_url}' => $this->kramar_unsub_link,
			],
			'items'       => $items,
			'items_total' => $this->kramar_cart_total,
		];
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_content_html(): string {
		return '';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_content_plain(): string {
		return '';
	}
}
