<?php
/**
 * SMTP integration and wp_mail interception.
 *
 * @package MailDoctor
 */

namespace MailDoctor;

require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-debug.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-init.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-config.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-profile.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-message.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-async.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-transport.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-fallback.php';
require_once MAIL_DOCTOR_PATH . 'includes/mail/mailer/modules/module-mailer-context.php';

use DateTimeImmutable;
use DateTimeZone;
use MailDoctor\Alerts;
use MailDoctor\Helpers\Settings;
use MailDoctor\Transports\Generic_Http;
use MailDoctor\Transports\Mailgun;
use MailDoctor\Transports\Postmark;
use MailDoctor\Transports\SendGrid;
use MailDoctor\Transports\Ses;
use MailDoctor\Transports\SparkPost;
use PHPMailer\PHPMailer\PHPMailer;
use WP_Error;
use function sanitize_key;

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

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

/**
 * Mailer service responsible for configuring SMTP and logging attempts.
 */
class Mailer {

	/**
	 * Event context for the current mail invocation.
	 *
	 * @var string|null
	 */
	protected static $current_event = null;

	/**
	 * Order context for the current mail invocation.
	 *
	 * @var int|null
	 */
	protected static $current_order_id = null;

	/**
	 * Email class context for WooCommerce emails.
	 *
	 * @var string|null
	 */
	protected static $current_email_class = null;

	/**
	 * Woo email identifier for the current invocation.
	 *
	 * @var string|null
	 */
	protected static $current_email_id = null;

	/**
	 * Track whether SMTP override should run for the current email.
	 *
	 * @var bool
	 */
	protected static $should_override = true;

	/**
	 * Force override flag for explicitly requested sends (e.g. test email).
	 *
	 * @var bool
	 */
	protected static $force_override = false;

	/**
	 * Retry metadata carried to next wp_mail invocation.
	 *
	 * @var array<string, mixed>
	 */
	protected static $retry_context = array();

	/**
	 * Currently active log id for header injection.
	 *
	 * @var int|null
	 */
	protected static $active_log_id = null;

	/**
	 * Idempotency key for the current mail attempt.
	 *
	 * @var string|null
	 */
	protected static $idempotency_key = null;

	/**
	 * Time bucket associated with idempotency calculations.
	 *
	 * @var int|null
	 */
	protected static $idempotency_bucket = null;

	/**
	 * Whether the current invocation was deduplicated.
	 *
	 * @var bool
	 */
	protected static $idempotency_duplicate = false;

	/**
	 * Active SMTP profile key for the current invocation.
	 *
	 * @var string|null
	 */
	protected static $active_profile_key = null;

	/**
	 * Active SMTP credentials for the current invocation.
	 *
	 * @var array<string, mixed>
	 */
	protected static $active_profile = array();

	/**
	 * Attachment metadata captured for the current invocation.
	 *
	 * @var array<int, array<string, mixed>>
	 */
	protected static $attachment_meta = array();

	/**
	 * Aggregate attachment size for the current invocation.
	 *
	 * @var int
	 */
	protected static $attachment_total = 0;

	/**
	 * Async queue entries scheduled for shutdown processing.
	 *
	 * @var array<int>
	 */
	protected static $async_queue = array();

	/**
	 * Whether the mailer is actively processing an async dispatch.
	 *
	 * @var bool
	 */
	protected static $processing_async = false;

	/**
	 * Threading headers for the current invocation.
	 *
	 * @var array{message_id: string|null, in_reply_to: string|null}
	 */
	protected static $thread_headers = array(
		'message_id'  => null,
		'in_reply_to' => null,
	);

	/**
	 * Correlation identifier for current invocation.
	 *
	 * @var string|null
	 */
	protected static $correlation_id = null;

	/**
	 * When true, bypasses plugin overrides (used for fallback transport).
	 *
	 * @var bool
	 */
	protected static $bypass_plugin = false;

	/**
	 * Track logs that already attempted fallback delivery.
	 *
	 * @var array<int, bool>
	 */
	protected static $fallback_attempted = array();

	use Mailer_Debug_Trait;
	use Mailer_Init_Trait;
	use Mailer_Config_Trait;
	use Mailer_Profile_Trait;
	use Mailer_Message_Trait;
	use Mailer_Async_Trait;
	use Mailer_Transport_Trait;
	use Mailer_Fallback_Trait;
	use Mailer_Context_Trait;

	/**
	 * Emit a structured trace line when MAILDBG is enabled.
	 *
	 * @param string               $stage   Stage identifier.
	 * @param array<string, mixed> $context Additional data to include.
	 * @return void
	 */
	public static function trace_maildbg( string $stage, array $context = array() ): void {
		self::trace_event( $stage, $context );
	}
}
