<?php
/**
 * PostGate Email Notification Handler
 *
 * Handles sending email notifications for manual order creation events.
 * Provides customizable email templates with variable substitution for
 * dynamic content personalization.
 *
 * @package PostGate
 * @subpackage Admin
 * @since 1.0.0
 * @author QodeSphere
 * @license GPL-2.0+
 */

defined( 'ABSPATH' ) || exit;

/**
 * PostGate Email Notification Class
 *
 * Manages email notifications sent when administrators manually create orders.
 * This is particularly useful during webhook failures to ensure customers are
 * informed about their purchases and access grants.
 *
 * Features:
 * - Template variable substitution for personalized emails
 * - Customizable sender information (name and email)
 * - HTML and plain text email support
 * - WordPress mail filters and hooks integration
 * - Error logging for failed email delivery
 * - Configurable enable/disable option
 *
 * Template Variables:
 * - {user_name}: Customer's display name
 * - {user_email}: Customer's email address
 * - {product_name}: Name of the purchased product
 * - {amount}: Purchase amount formatted with currency
 * - {order_id}: Unique order identifier
 * - {site_name}: WordPress site name
 * - {site_url}: WordPress site URL
 * - {admin_name}: Administrator who created the order
 *
 * @since 1.0.0
 */
class PostGate_Email_Notification {

	/**
	 * Send manual order notification email.
	 *
	 * Sends a customized email to the customer notifying them about a manually
	 * created order. Uses template variables for personalization and respects
	 * the plugin's email notification settings.
	 *
	 * @since 1.0.0
	 *
	 * @param array $order_data Order details for email generation.
	 *     @type int    $order_id       Unique order ID.
	 *     @type int    $user_id        Customer user ID.
	 *     @type int    $admin_id       Administrator who created the order.
	 *     @type string $product_id     Stripe product ID.
	 *     @type string $product_name   Product name for display.
	 *     @type int    $amount         Order amount in cents (minor units).
	 *     @type string $currency       Three-letter currency code.
	 *     @type bool   $access_granted Whether access was granted with order.
	 *     @type string $notes          Optional admin notes.
	 *
	 * @return bool True if email sent successfully, false otherwise.
	 */
	public static function send_manual_order_notification( array $order_data ): bool {
		// Check if email notifications are enabled for manual orders
		$enabled = get_option( 'postgate_manual_order_email_enabled', false );

		if ( ! $enabled ) {
			return false;
		}

		// Get customer user data
		$user = get_userdata( $order_data['user_id'] ?? 0 );
		if ( ! $user ) {
			PostGate_Logger::warning( 'Cannot send email - invalid user ID', [ 'user_id' => $order_data['user_id'] ?? 0 ] );
			return false;
		}

		// Get admin user data
		$admin_user = get_userdata( $order_data['admin_id'] ?? 0 );
		$admin_name = $admin_user ? $admin_user->display_name : __( 'Administrator', 'postgate' );

		// Format amount with currency using Product_Utils
		$amount = PostGate_Product_Utils::format_price(
			$order_data['amount'] ?? 0,
			$order_data['currency'] ?? 'USD'
		);

		// Prepare template variables
		$variables = array(
			'{user_name}' => $user->display_name,
			'{user_email}' => $user->user_email,
			'{product_name}' => $order_data['product_name'] ?? __( 'Unknown Product', 'postgate' ),
			'{amount}' => $amount,
			'{order_id}' => $order_data['order_id'] ?? '',
			'{site_name}' => get_bloginfo( 'name' ),
			'{site_url}' => get_bloginfo( 'url' ),
			'{admin_name}' => $admin_name,
		);

		// Get email settings with defaults
		$from_name = get_option( 'postgate_email_notification_from_name', get_bloginfo( 'name' ) );
		$from_email = get_option( 'postgate_email_notification_from_email', get_bloginfo( 'admin_email' ) );
		$subject = get_option( 'postgate_manual_order_email_subject', __( 'New Order Created - Action Required', 'postgate' ) );
		$message = get_option( 'postgate_manual_order_email_message', self::get_default_message() );

		// Replace template variables
		$subject = self::replace_variables( $subject, $variables );
		$message = self::replace_variables( $message, $variables );

		// Set email headers
		$headers = array(
			'Content-Type: text/plain; charset=UTF-8',
			sprintf( 'From: %s <%s>', $from_name, $from_email ),
		);

		/**
		 * Filters the email notification headers before sending.
		 *
		 * @since 1.0.0
		 * @hook postgate_email_notification_headers
		 *
		 * @param {array} $headers    Email headers array.
		 * @param {array} $order_data Order data array.
		 * @return {array} Modified headers array.
		 */
		$headers = apply_filters( 'postgate_email_notification_headers', $headers, $order_data );

		/**
		 * Filters the email notification subject before sending.
		 *
		 * @since 1.0.0
		 * @hook postgate_email_notification_subject
		 *
		 * @param {string} $subject    Email subject line.
		 * @param {array}  $order_data Order data array.
		 * @return {string} Modified subject line.
		 */
		$subject = apply_filters( 'postgate_email_notification_subject', $subject, $order_data );

		/**
		 * Filters the email notification message body before sending.
		 *
		 * @since 1.0.0
		 * @hook postgate_email_notification_message
		 *
		 * @param {string} $message    Email message body.
		 * @param {array}  $order_data Order data array.
		 * @return {string} Modified message body.
		 */
		$message = apply_filters( 'postgate_email_notification_message', $message, $order_data );

		// Send email
		$sent = wp_mail( $user->user_email, $subject, $message, $headers );

		if ( ! $sent ) {
			PostGate_Logger::error( 'Failed to send email notification', [
				'recipient_email' => $user->user_email,
				'order_id' => $order_data['order_id'] ?? 'unknown',
				'user_id' => $user->ID,
			] );
		}

		/**
		 * Fires after an email notification send attempt.
		 *
		 * @since 1.0.0
		 * @hook postgate_email_notification_sent
		 *
		 * @param {bool}  $sent       Whether email was sent successfully.
		 * @param {array} $order_data Order data array.
		 */
		do_action( 'postgate_email_notification_sent', $sent, $order_data );

		return $sent;
	}

	/**
	 * Replace template variables in text.
	 *
	 * Performs case-insensitive replacement of template variables with
	 * their corresponding values.
	 *
	 * @since 1.0.0
	 *
	 * @param string $text      Text containing template variables.
	 * @param array  $variables Associative array of variable => value pairs.
	 *
	 * @return string Text with variables replaced.
	 */
	private static function replace_variables( string $text, array $variables ): string {
		foreach ( $variables as $placeholder => $value ) {
			$text = str_replace( $placeholder, $value, $text );
		}

		return $text;
	}

	/**
	 * Get default email message template.
	 *
	 * Returns the default email message with template variables
	 * for manual order notifications.
	 *
	 * @since 1.0.0
	 *
	 * @return string Default email message template.
	 */
	private static function get_default_message(): string {
		return __(
			"Hello {user_name},\n\nA new order has been manually created for your account by our team.\n\nOrder Details:\n- Product: {product_name}\n- Amount: {amount}\n- Order ID: {order_id}\n\nYou can now access your content at {site_url}.\n\nIf you have any questions, please don't hesitate to contact us.\n\nBest regards,\n{site_name} Team\n\n---\nThis order was created by {admin_name}",
			'postgate'
		);
	}
}
