<?php
/**
 * Prepare email HTML for reliable image delivery (absolute URLs + CID embeds).
 *
 * @package SuiteMkt3k
 */

namespace SuiteMkt3k\Email;

defined( 'ABSPATH' ) || exit;

final class Email_Assets {

	/** @var array<string, string> cid => absolute file path */
	private static $embed_queue = array();

	public static function register(): void {
		add_action( 'phpmailer_init', array( __CLASS__, 'embed_on_phpmailer' ), 20 );
	}

	/**
	 * Normalize image URLs and queue local files for inline embedding.
	 */
	public static function prepare( string $html ): string {
		self::$embed_queue = array();

		if ( '' === trim( $html ) ) {
			return $html;
		}

		$html = self::absolutize_src_attributes( $html );
		$html = self::embed_local_images( $html );

		return $html;
	}

	/**
	 * @param \PHPMailer\PHPMailer\PHPMailer $phpmailer
	 */
	public static function embed_on_phpmailer( $phpmailer ): void {
		if ( empty( self::$embed_queue ) || ! is_object( $phpmailer ) ) {
			return;
		}
		if ( ! self::is_suitemkt3k_mail( $phpmailer ) || ! method_exists( $phpmailer, 'addEmbeddedImage' ) ) {
			self::$embed_queue = array();
			return;
		}
		foreach ( self::$embed_queue as $cid => $path ) {
			if ( is_readable( $path ) ) {
				try {
					$phpmailer->addEmbeddedImage( $path, $cid );
				} catch ( \Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
					continue;
				}
			}
		}
		self::$embed_queue = array();
	}

	/**
	 * @param \PHPMailer\PHPMailer\PHPMailer $phpmailer
	 */
	private static function is_suitemkt3k_mail( $phpmailer ): bool {
		if ( ! method_exists( $phpmailer, 'getCustomHeaders' ) ) {
			return false;
		}
		foreach ( (array) $phpmailer->getCustomHeaders() as $header ) {
			if ( is_array( $header ) && isset( $header[0] ) && Mailer::HEADER_TAG === $header[0] ) {
				return true;
			}
		}
		return false;
	}

	private static function absolutize_src_attributes( string $html ): string {
		return (string) preg_replace_callback(
			'/\s(src|background)=([\'"])([^\'"]+)\2/i',
			static function ( array $m ) {
				$url = self::to_absolute_url( $m[3] );
				return ' ' . $m[1] . '=' . $m[2] . esc_url( $url ) . $m[2];
			},
			$html
		);
	}

	private static function embed_local_images( string $html ): string {
		return (string) preg_replace_callback(
			'/<img([^>]+)src=([\'"])([^\'"]+)\2([^>]*)>/i',
			static function ( array $m ) {
				$url  = $m[3];
				$path = self::url_to_local_path( $url );
				if ( ! $path ) {
					return $m[0];
				}
				$cid = 'wmk' . substr( md5( $path . $url ), 0, 16 );
				self::$embed_queue[ $cid ] = $path;
				return '<img' . $m[1] . 'src="cid:' . $cid . '"' . $m[4] . '>';
			},
			$html
		);
	}

	public static function to_absolute_url( string $url ): string {
		$url = trim( $url );
		if ( '' === $url || preg_match( '#^https?://#i', $url ) || 0 === strpos( strtolower( $url ), 'cid:' ) ) {
			return $url;
		}
		if ( 0 === strpos( $url, '//' ) ) {
			return ( is_ssl() ? 'https:' : 'http:' ) . $url;
		}
		return home_url( '/' . ltrim( $url, '/' ) );
	}

	private static function url_to_local_path( string $url ): string {
		$url = self::to_absolute_url( $url );
		if ( ! preg_match( '#^https?://#i', $url ) ) {
			return '';
		}
		$uploads = wp_upload_dir();
		if ( empty( $uploads['baseurl'] ) || empty( $uploads['basedir'] ) ) {
			return '';
		}
		if ( 0 !== strpos( $url, $uploads['baseurl'] ) ) {
			return '';
		}
		$rel  = substr( $url, strlen( $uploads['baseurl'] ) );
		$path = $uploads['basedir'] . $rel;
		return is_readable( $path ) ? $path : '';
	}

	public static function attachment_url( int $attachment_id, string $size = 'medium' ): string {
		if ( $attachment_id <= 0 ) {
			return '';
		}
		$url = wp_get_attachment_image_url( $attachment_id, $size );
		return $url ? self::to_absolute_url( $url ) : '';
	}
}
