<?php
/**
 * Shared HTML email wrapper renderer for WP PowerSuite.
 *
 * @package WP_PowerSuite\Email
 * @since   1.0.0
 */

namespace WP_PowerSuite\Email;

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

/**
 * Renders a complete HTML email document with consistent layout.
 */
final class EmailRenderer {

	/** @var array<string, string>|null */
	private static ?array $cached_branding = null;

	/**
	 * Wrap inner content in the standard plugin email shell.
	 *
	 * @param array{
	 *   content: string,
	 *   title?: string,
	 *   badge?: string,
	 *   preheader?: string,
	 *   logo_url?: string,
	 *   site_name?: string,
	 *   footer?: string,
	 *   footer_brand?: string,
	 *   config?: array<string, mixed>,
	 * } $args
	 */
	public static function wrap( array $args ): string {
		$content = (string) ( $args['content'] ?? '' );
		if ( $content === '' ) {
			return '';
		}

		$config     = EmailDesign::resolveConfig( $args['config'] ?? self::getBrandingConfig() );
		$title      = isset( $args['title'] ) ? (string) $args['title'] : '';
		$badge      = isset( $args['badge'] ) ? (string) $args['badge'] : '';
		$preheader  = isset( $args['preheader'] ) ? (string) $args['preheader'] : '';
		$footer     = isset( $args['footer'] ) ? (string) $args['footer'] : '';
		$footer_brand = isset( $args['footer_brand'] ) ? (string) $args['footer_brand'] : '';
		if ( $footer_brand === '' ) {
			$footer_brand = self::defaultFooterBrand( $footer_brand );
		}
		$logo_url   = isset( $args['logo_url'] ) ? esc_url_raw( (string) $args['logo_url'] ) : $config['logo'];
		$site_name  = isset( $args['site_name'] ) ? (string) $args['site_name'] : wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );

		$view = __DIR__ . '/views/wrapper.php';
		if ( ! is_readable( $view ) ) {
			return $content;
		}

		ob_start();
		include $view;
		return (string) ob_get_clean();
	}

	/**
	 * Standard HTML mail headers.
	 *
	 * @param array<int, string> $extra
	 * @return list<string>
	 */
	public static function headers( array $extra = [] ): array {
		$headers = array_values(
			array_filter(
				array_map(
					static fn( $h ) => is_string( $h ) ? trim( $h ) : '',
					$extra
				)
			)
		);

		$has_type = false;
		foreach ( $headers as $header ) {
			if ( stripos( $header, 'Content-Type:' ) === 0 ) {
				$has_type = true;
				break;
			}
		}
		if ( ! $has_type ) {
			array_unshift( $headers, 'Content-Type: text/html; charset=UTF-8' );
		}

		return $headers;
	}

	/**
	 * Register a one-shot plain-text AltBody on PHPMailer.
	 */
	public static function withPlainAltBody( string $plain, callable $send ): mixed {
		add_action(
			'phpmailer_init',
			$callback = static function ( $phpmailer ) use ( $plain ): void {
				$phpmailer->AltBody = $plain;
			},
			99999
		);

		try {
			return $send();
		} finally {
			remove_action( 'phpmailer_init', $callback, 99999 );
		}
	}

	/**
	 * Basic HTML → plain text for AltBody fallbacks.
	 */
	public static function htmlToPlain( string $html ): string {
		$text = preg_replace( '/<br\s*\/?>/i', "\n", $html );
		$text = preg_replace( '/<\/p>/i', "\n\n", (string) $text );
		$text = wp_strip_all_tags( (string) $text );
		$text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
		$text = preg_replace( "/[ \t]+\n/", "\n", $text );
		$text = preg_replace( "/\n{3,}/", "\n\n", (string) $text );
		return trim( (string) $text );
	}

	/**
	 * Pull branding from custom-wp-emails when available (cached per request).
	 *
	 * @return array<string, mixed>
	 */
	public static function getBrandingConfig(): array {
		if ( self::$cached_branding !== null ) {
			return self::$cached_branding;
		}

		$config = [];
		if ( class_exists( '\CustomWpEmails\Includes\SystemEmailService' ) ) {
			$raw = get_option( \CustomWpEmails\Includes\SystemEmailService::get_option_key(), [] );
			if ( is_array( $raw ) && ! empty( $raw['template_settings'] ) && is_array( $raw['template_settings'] ) ) {
				$config = $raw['template_settings'];
			}
		}

		if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel' ) ) {
			$config = self::mergeWhiteLabelBranding( $config );
		}

		self::$cached_branding = $config;
		return self::$cached_branding;
	}

	/**
	 * Merge white-label email branding over Custom WP Emails template settings.
	 *
	 * @param array<string, mixed> $config
	 * @return array<string, mixed>
	 */
	private static function mergeWhiteLabelBranding( array $config ): array {
		$branding = \WP_PowerSuite\Core\WhiteLabel::get_email_branding();
		$logo     = trim( (string) ( $branding['logo_url'] ?? '' ) );
		if ( $logo !== '' ) {
			$config['logo'] = $logo;
		}

		$footer = trim( (string) ( $branding['footer_text'] ?? '' ) );
		if ( $footer !== '' ) {
			$config['footer_brand_default'] = $footer;
		}

		return $config;
	}

	/**
	 * Default footer brand line for plugin emails.
	 */
	public static function defaultFooterBrand( string $fallback = '' ): string {
		if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel' ) ) {
			$branding = \WP_PowerSuite\Core\WhiteLabel::get_email_branding();
			$footer   = trim( (string) ( $branding['footer_text'] ?? '' ) );
			if ( $footer !== '' ) {
				return $footer;
			}
			if ( \WP_PowerSuite\Core\WhiteLabel::shouldHidePoweredBy() ) {
				return $fallback;
			}
		}

		$config = self::getBrandingConfig();
		$from_module = trim( (string) ( $config['footer_brand_default'] ?? '' ) );
		if ( $from_module !== '' ) {
			return $from_module;
		}

		return $fallback;
	}

	public static function bustBrandingCache(): void {
		self::$cached_branding = null;
	}

	/**
	 * Default accent from branding or fallback.
	 */
	public static function accentColor(): string {
		$cfg = EmailDesign::resolveConfig( self::getBrandingConfig() );
		return $cfg['accent_color'];
	}

	/**
	 * Branding logo URL from Custom WP Emails template settings, if configured.
	 */
	public static function brandingLogoUrl(): string {
		if ( class_exists( '\WP_PowerSuite\Core\WhiteLabel' ) ) {
			$url = \WP_PowerSuite\Core\WhiteLabel::logoUrl();
			if ( $url !== '' ) {
				return $url;
			}
		}

		$cfg = EmailDesign::resolveConfig( self::getBrandingConfig() );
		return (string) ( $cfg['logo'] ?? '' );
	}
}
