<?php
/**
 * Mailer — sends emails using WordPress mail (SMTP-compatible via any mail plugin).
 *
 * @package CartCue
 */

namespace CartCue;

defined( 'ABSPATH' ) || exit;

class Mailer {

	/**
	 * Send an HTML email.
	 *
	 * @param string $to       Recipient email address.
	 * @param string $subject  Email subject (already variable-processed).
	 * @param string $body     Email body HTML (already variable-processed).
	 * @param array  $args {
	 *     @type string $from_name   Sender name.
	 *     @type string $from_email  Sender email.
	 *     @type string $reply_to    Reply-to address.
	 *     @type string $bcc         Comma-separated BCC addresses.
	 *     @type bool   $plain       Send as plain text (no HTML wrapper).
	 * }
	 * @return bool True if mail was accepted for delivery.
	 */
	public function send( string $to, string $subject, string $body, array $args = [] ): bool {
		if ( ! is_email( $to ) ) {
			return false;
		}

		$mail_context = array_merge(
			$args,
			[
				'customer_email' => $to,
				'_is_test'       => ! empty( $args['is_test'] ) || ! empty( $args['_is_test'] ),
			]
		);
		if ( ! EnvironmentGuard::allows_live_email( $mail_context ) ) {
			return false;
		}

		$settings   = get_option( 'cartcue_settings', [] );
		$from_name  = sanitize_text_field( $args['from_name']  ?? $settings['from_name']  ?? get_bloginfo( 'name' ) );
		$from_email = sanitize_email( $args['from_email'] ?? $settings['from_email'] ?? get_option( 'admin_email' ) );
		$plain      = ! empty( $args['plain'] );

		if ( $plain ) {
			$mail_body = wp_strip_all_tags( $body );
			$mail_body = html_entity_decode( $mail_body, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
		} else {
			$mail_body = $this->wrap_in_template( $body );
		}

		$workflow_id = (int) ( $args['workflow_id'] ?? 0 );
		$mail_body   = apply_filters( 'cartcue_pre_send_email', $mail_body, $workflow_id, array_merge( $args, [
			'customer_email' => $to,
			'subject'        => $subject,
			'is_plain'       => $plain,
			'raw_body'       => $body,
		] ) );

		$headers = [
			sprintf( 'From: %s <%s>', $from_name, $from_email ),
		];
		$recipient = strtolower( $to );
		$unsub_url = Unsubscribe::signed_url( $recipient );
		if ( $unsub_url ) {
			$headers[] = 'List-Unsubscribe: <' . esc_url_raw( $unsub_url ) . '>, <mailto:' . sanitize_email( get_option( 'admin_email' ) ) . '?subject=unsubscribe>';
			$headers[] = 'List-Unsubscribe-Post: List-Unsubscribe=One-Click';
		}
		$headers[] = 'Precedence: bulk';
		$headers[] = 'X-Auto-Response-Suppress: All';

		if ( $plain ) {
			$headers[] = 'Content-Type: text/plain; charset=UTF-8';
		} else {
			$headers[] = 'Content-Type: text/html; charset=UTF-8';
		}

		if ( ! empty( $args['reply_to'] ) && is_email( $args['reply_to'] ) ) {
			$headers[] = 'Reply-To: ' . sanitize_email( $args['reply_to'] );
		}

		$bcc_raw = $args['bcc'] ?? '';
		if ( is_string( $bcc_raw ) && '' !== trim( $bcc_raw ) ) {
			$bcc_addrs = [];
			foreach ( array_map( 'trim', explode( ',', $bcc_raw ) ) as $addr ) {
				$addr = sanitize_email( $this->strip_template_placeholders( $addr ) );
				if ( is_email( $addr ) ) {
					$bcc_addrs[] = $addr;
				}
			}
			if ( ! empty( $bcc_addrs ) ) {
				$headers[] = 'Bcc: ' . implode( ', ', array_unique( $bcc_addrs ) );
			}
		}

		if ( ! $plain ) {
			add_filter( 'wp_mail_content_type', [ $this, 'set_html_content_type' ] );
		}

		$result = wp_mail( $to, $subject, $mail_body, $headers );

		if ( ! $plain ) {
			remove_filter( 'wp_mail_content_type', [ $this, 'set_html_content_type' ] );
		}

		return (bool) $result;
	}

	/** Remove unreplaced {{ }} tokens before validating email. */
	private function strip_template_placeholders( string $s ): string {
		return trim( preg_replace( '/\{\{[^}]+\}\}/', '', $s ) );
	}

	/** @internal Used as a filter callback. */
	public function set_html_content_type(): string {
		return 'text/html';
	}

	// -------------------------------------------------------------------------
	// HTML template wrapper
	// -------------------------------------------------------------------------

	/**
	 * Wrap body content in a styled HTML email shell.
	 * Falls back to a simple WooCommerce-style table if WC mailer is unavailable.
	 *
	 * @param string $content
	 * @return string
	 */
	/**
	 * Wrap body HTML for previews (same shell as outbound mail).
	 */
	public function wrap_for_preview( string $content ): string {
		// Admin preview iframe inherits OS dark mode; always show the light layout.
		return $this->wrap_in_template( $content, true );
	}

	private function wrap_in_template( string $content, bool $light_only = false ): string {
		// Check for custom HTML template override in settings.
		$ap_settings = get_option( 'cartcue_settings', [] );
		$custom_tmpl = trim( $ap_settings['email_template_html'] ?? '' );
		if ( $custom_tmpl && wp_str_contains( $custom_tmpl, '{{BODY}}' ) ) {
			return str_replace( '{{BODY}}', $content, $custom_tmpl );
		}

		$shop_name = esc_html( get_bloginfo( 'name' ) );
		$accent    = esc_attr( apply_filters( 'cartcue_email_accent_color', '#7952B3' ) );
		$home      = esc_url( home_url() );
		$home_lbl  = esc_html( home_url() );
		$year      = esc_html( gmdate( 'Y' ) );
		$body      = wp_kses_post( $content );

		$color_scheme_meta = $light_only
			? '<meta name="color-scheme" content="light">'
			: '<meta name="color-scheme" content="light dark">'
				. '<meta name="supported-color-schemes" content="light dark">';

		$dark_styles = $light_only ? '' : '<style>@media (prefers-color-scheme:dark){'
			. '.cc-wrap{background:#1a1a2e!important;}'
			. '.cc-body{color:#e0e0e0!important;}'
			. '.cc-body>div{color:#e0e0e0!important;}'
			. '.cc-footer{background:#12122a!important;color:#aaa!important;}'
			. '.cc-footer a{color:#AFA9EC!important;}'
			. '}</style>';

		return '<!DOCTYPE html><html><head>'
			. '<meta charset="UTF-8">'
			. '<meta name="viewport" content="width=device-width, initial-scale=1">'
			. $color_scheme_meta
			. '<title>' . $shop_name . '</title>'
			. $dark_styles
			. '</head>'
			. '<body style="margin:0;padding:0;background:#f5f5f5;font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,Oxygen,Ubuntu,sans-serif;">'
			. '<div class="cc-wrap" style="max-width:600px;margin:40px auto;background:#fff;border-radius:6px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.08);">'
			. '<div class="cc-header" style="background:' . $accent . ';padding:28px 40px;">'
			. '<h1 style="margin:0;color:#fff;font-size:22px;font-weight:600;letter-spacing:.3px;">' . $shop_name . '</h1>'
			. '</div>'
			. '<div class="cc-body" style="padding:36px 40px;color:#333;line-height:1.7;font-size:15px;">' . $body . '</div>'
			. '<div class="cc-footer" style="background:#f9f9f9;border-top:1px solid #eee;padding:18px 40px;text-align:center;font-size:12px;color:#999;">'
			. '&copy; ' . $year . ' ' . $shop_name . ' &nbsp;&bull;&nbsp;'
			. '<a href="' . $home . '" style="color:#999;">' . $home_lbl . '</a>'
			. '</div></div></body></html>';
	}
}
