<?php
/**
 * Core token map generation routines.
 *
 * @package MailDoctor
 */

namespace MailDoctor;

use WC_Order;

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

/**
 * Builds the collection of token replacements.
 */
trait WPMD_Email_Tokens_Core {

	/**
	 * Cache group used for token maps.
	 */
	public const CACHE_GROUP = 'mail_doctor_email_tokens';

	/**
	 * Provide a map of template tokens to sanitized values.
	 *
	 * @param WC_Order|null        $order   Optional WooCommerce order.
	 * @param array<string, mixed> $context Optional rendering context.
	 * @return array<string, string>
	 */
	public static function get_map( $order = null, array $context = array() ): array {
		$has_wc_order = class_exists( 'WC_Order' );
		$order_id     = ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_id() : 0;
		$email_type   = isset( $context['email_type'] ) ? sanitize_key( (string) $context['email_type'] ) : 'generic';

		if ( $order_id > 0 ) {
			$cache_key = implode(
				':',
				array(
					$email_type,
					(int) $order_id,
					(bool) ( $context['preview'] ?? false ),
				)
			);

			$cached = wp_cache_get( $cache_key, self::CACHE_GROUP );
			if ( is_array( $cached ) ) {
				return $cached;
			}
		}

		$tokens = self::build_tokens( $has_wc_order && $order instanceof WC_Order ? $order : null, $context );

		if ( isset( $cache_key ) ) {
			wp_cache_set( $cache_key, $tokens, self::CACHE_GROUP, MINUTE_IN_SECONDS );
		}

		return $tokens;
	}

	/**
	 * Build token map.
	 *
	 * @param WC_Order|null        $order   Optional order instance.
	 * @param array<string, mixed> $context Rendering context.
	 * @return array<string, string>
	 */
	protected static function build_tokens( $order = null, array $context = array() ): array {
		$has_wc_order = class_exists( 'WC_Order' );
		$order_id     = ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_id() : 0;

		$shop_name = get_bloginfo( 'name' );

		$extra_tokens = array();
		if ( ! empty( $context['extra_tokens'] ) && is_array( $context['extra_tokens'] ) ) {
			$extra_tokens = $context['extra_tokens'];
		}

		// Resolve a store logo URL (Woo email header image → theme custom logo → site icon).
		$logo_url  = '';
		$wc_header = (string) get_option( 'woocommerce_email_header_image' );
		if ( $wc_header ) {
			$logo_url = esc_url_raw( $wc_header );
		}
		if ( ! $logo_url ) {
			$custom_logo_id = (int) get_theme_mod( 'custom_logo' );
			if ( $custom_logo_id ) {
				$maybe = wp_get_attachment_image_url( $custom_logo_id, 'full' );
				if ( $maybe ) {
					$logo_url = esc_url_raw( $maybe );
				}
			}
		}
		if ( ! $logo_url ) {
			$site_icon = get_site_icon_url( 192 );
			if ( $site_icon ) {
				$logo_url = esc_url_raw( $site_icon );
			}
		}

		// Determine first product image URL for the order (if available).
		$first_product_image_url = '';
		if ( $has_wc_order && $order instanceof WC_Order ) {
			foreach ( $order->get_items() as $item ) {
				$product = is_callable( array( $item, 'get_product' ) ) ? $item->get_product() : null;
				if ( $product ) {
					$img_id = $product->get_image_id();
					if ( $img_id ) {
						$maybe = wp_get_attachment_image_url( $img_id, 'medium' );
						if ( $maybe ) {
							$first_product_image_url = esc_url_raw( $maybe );
							break;
						}
					}
				}
			}
		}

		$brand_html = '';
		if ( $logo_url ) {
			$brand_html = '<img src="' . esc_url( $logo_url ) . '" alt="' . esc_attr( $shop_name ) . '" style="max-width:200px;height:auto;" />';
		} else {
			$brand_html = '<span class="wpmd-brand-text" style="font-weight:700;font-size:20px;">' . esc_html( $shop_name ) . '</span>';
		}

		$tokens = array(
			'order_number'            => ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_order_number() : '',
			'order_id'                => $order_id ? (string) $order_id : '',
			'order_status'            => ( $has_wc_order && $order instanceof WC_Order && function_exists( 'wc_get_order_status_name' ) ) ? wc_get_order_status_name( $order->get_status() ) : '',
			'order_date'              => ( $has_wc_order && $order instanceof WC_Order && function_exists( 'wc_format_datetime' ) ) ? wc_format_datetime( $order->get_date_created() ) : '',
			'order_total'             => ( $has_wc_order && $order instanceof WC_Order ) ? wp_strip_all_tags( $order->get_formatted_order_total() ) : '',
			'customer_name'           => ( $has_wc_order && $order instanceof WC_Order ) ? trim( $order->get_formatted_billing_full_name() ?: $order->get_billing_first_name() ) : '',
			'customer_email'          => ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_billing_email() : '',
			'billing_address'         => ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_formatted_billing_address( '<br />' ) : '',
			'shipping_address'        => ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_formatted_shipping_address( '<br />' ) : '',
			'payment_method'          => ( $has_wc_order && $order instanceof WC_Order ) ? $order->get_payment_method_title() : '',
			'shipping_method'         => ( $has_wc_order && $order instanceof WC_Order ) ? self::format_shipping_method( $order ) : '',
			'items_table'             => ( $has_wc_order && $order instanceof WC_Order ) ? self::build_items_table( $order, $context ) : '',
			'download_links'          => ( $has_wc_order && $order instanceof WC_Order ) ? self::build_download_links( $order ) : '',
			'refund_amount'           => ( $has_wc_order && $order instanceof WC_Order ) ? self::format_refund_total( $order ) : '',
			'shop_name'               => $shop_name,
			'shop_logo_url'           => $logo_url,
			'shop_logo_img'           => $logo_url ? '<img src="' . esc_url( $logo_url ) . '" alt="' . esc_attr( $shop_name ) . '" style="max-width:200px;height:auto;" />' : '',
			'shop_brand'              => $brand_html,
			'first_product_image_url' => $first_product_image_url,
			'first_product_image_img' => $first_product_image_url ? '<img src="' . esc_url( $first_product_image_url ) . '" alt="" style="max-width:120px;height:auto;" />' : '',
			'site_url'                => home_url( '/' ),
			'unsubscribe_link'        => self::build_unsubscribe_link( $order ),
			'reset_url'               => self::resolve_reset_url( $context ),
			'customer_note'           => isset( $extra_tokens['customer_note'] ) ? wp_kses_post( (string) $extra_tokens['customer_note'] ) : '',
		);

		if ( isset( $context['subject'] ) ) {
			$tokens['subject'] = (string) $context['subject'];
		}

		if ( isset( $context['heading'] ) ) {
			$tokens['heading'] = (string) $context['heading'];
		}

		if ( ! empty( $context['extra_tokens'] ) && is_array( $context['extra_tokens'] ) ) {
			foreach ( $context['extra_tokens'] as $token => $value ) {
				$token_key = sanitize_key( (string) $token );
				if ( '' === $token_key ) {
					continue;
				}

				$tokens[ $token_key ] = is_scalar( $value ) ? (string) $value : '';
			}
		}

		/**
		 * Filter the resolved email token map.
		 *
		 * @param array<string, string> $tokens Token map.
		 * @param WC_Order|null         $order  Order instance.
		 * @param array<string, mixed>  $context Rendering context.
		 */
		return apply_filters( 'mail_doctor_email_tokens', $tokens, $order, $context );
	}
}
