<?php
/**
 * SMTP Email Handler Class
 *
 * Handles SMTP email sending for the subscription system.
 *
 * @link       https://mediahubster.in
 * @since      1.0.4
 *
 * @package    Subs_Sys
 * @subpackage Subs_Sys/includes
 */

// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * SMTP Email Handler Class
 *
 * This class handles SMTP email configuration and sending.
 *
 * @since      1.0.4
 * @package    Subs_Sys
 * @subpackage Subs_Sys/includes
 * @author     Joe Youngblood <support@subscriptionplugin.com>
 */
class Subs_Sys_SMTP {

	/**
	 * Initialize the class and set up hooks
	 *
	 * @since 1.0.4
	 */
	public function __construct() {
		// Hook into WordPress mail system if SMTP is enabled
		if ( get_option( 'subscription_enable_smtp' ) ) {
			add_action( 'phpmailer_init', array( $this, 'configure_phpmailer' ) );
			add_filter( 'wp_mail_from', array( $this, 'set_from_email' ) );
			add_filter( 'wp_mail_from_name', array( $this, 'set_from_name' ) );
		}

		// Add AJAX handler for testing SMTP connection
		add_action( 'wp_ajax_test_smtp_connection', array( $this, 'test_smtp_connection' ) );
	}

	/**
	 * Configure PHPMailer to use SMTP
	 *
	 * @param PHPMailer|PHPMailer\PHPMailer\PHPMailer $phpmailer The PHPMailer instance
	 */
	public function configure_phpmailer( $phpmailer ) {
		// Set mailer to use SMTP
		$phpmailer->isSMTP();

		// SMTP configuration
		$phpmailer->Host = get_option( 'subscription_smtp_host', 'localhost' );
		$phpmailer->Port = get_option( 'subscription_smtp_port', 587 );
		
		// Encryption
		$encryption = get_option( 'subscription_smtp_encryption', '' );
		if ( ! empty( $encryption ) ) {
			$phpmailer->SMTPSecure = $encryption;
		}

		// Authentication
		if ( get_option( 'subscription_smtp_auth', 1 ) ) {
			$phpmailer->SMTPAuth = true;
			$phpmailer->Username = get_option( 'subscription_smtp_username', '' );
			$phpmailer->Password = get_option( 'subscription_smtp_password', '' );
		}

		// Additional settings for better compatibility
		$phpmailer->SMTPOptions = array(
			'ssl' => array(
				'verify_peer'       => false,
				'verify_peer_name'  => false,
				'allow_self_signed' => true
			)
		);

		// Enable debug mode for better error reporting
		$phpmailer->SMTPDebug = 2; // Enable verbose debug output
		$phpmailer->Debugoutput = function( $str, $level ) {
			error_log( "SMTP Debug: $str" );
		};

		// Set timeout for better error handling
		$phpmailer->Timeout = 30;
		$phpmailer->SMTPKeepAlive = false;
	}

	/**
	 * Set the from email address
	 *
	 * @param string $from_email Original from email
	 * @return string Modified from email
	 */
	public function set_from_email( $from_email ) {
		$custom_from_email = get_option( 'subscription_from_email' );
		return ! empty( $custom_from_email ) ? $custom_from_email : $from_email;
	}

	/**
	 * Set the from name
	 *
	 * @param string $from_name Original from name
	 * @return string Modified from name
	 */
	public function set_from_name( $from_name ) {
		$custom_from_name = get_option( 'subscription_from_name' );
		return ! empty( $custom_from_name ) ? $custom_from_name : $from_name;
	}

	/**
	 * Send email using configured SMTP settings
	 *
	 * @param string|array $to      Recipient email(s)
	 * @param string       $subject Email subject
	 * @param string       $message Email message
	 * @param string|array $headers Optional headers
	 * @param string|array $attachments Optional attachments
	 * @return bool True if email was sent successfully
	 */
	public function send_email( $to, $subject, $message, $headers = '', $attachments = array() ) {
		// Log email attempt
		error_log( "SMTP: Attempting to send email to: " . ( is_array( $to ) ? implode( ', ', $to ) : $to ) );
		
		// Use WordPress wp_mail function which will use our SMTP configuration
		$sent = wp_mail( $to, $subject, $message, $headers, $attachments );
		
		if ( $sent ) {
			error_log( "SMTP: Email sent successfully" );
		} else {
			error_log( "SMTP: Failed to send email" );
		}
		
		return $sent;
	}

	/**
	 * Test SMTP connection via AJAX
	 */
	public function test_smtp_connection() {
		// Verify nonce
		if ( ! wp_verify_nonce( $_POST['nonce'], 'test_smtp_nonce' ) ) {
			wp_send_json_error( array( 'message' => 'Security check failed' ) );
		}

		// Check user permissions
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Insufficient permissions' ) );
		}

		// Get test settings from POST data
		$smtp_host = sanitize_text_field( $_POST['smtp_host'] );
		$smtp_port = intval( $_POST['smtp_port'] );
		$smtp_encryption = sanitize_text_field( $_POST['smtp_encryption'] );
		$smtp_auth = intval( $_POST['smtp_auth'] );
		$smtp_username = sanitize_text_field( $_POST['smtp_username'] );
		$smtp_password = $_POST['smtp_password']; // Don't sanitize password
		$from_email = sanitize_email( $_POST['from_email'] );
		$from_name = sanitize_text_field( $_POST['from_name'] );

		// Validate required fields
		if ( empty( $smtp_host ) || empty( $smtp_port ) || empty( $from_email ) ) {
			wp_send_json_error( array( 'message' => 'Please fill in all required fields (Host, Port, From Email)' ) );
		}

		// SendGrid specific validation and recommendations
		if ( strpos( $smtp_host, 'sendgrid' ) !== false ) {
			if ( $smtp_port == 465 ) {
				wp_send_json_error( array( 
					'message' => 'SendGrid recommends using port 587 with TLS encryption, not port 465 with SSL. Please change to port 587 and TLS.' 
				) );
			}
			if ( $smtp_username !== 'apikey' ) {
				wp_send_json_error( array( 
					'message' => 'For SendGrid, the username should be exactly "apikey" (not your email or actual username)' 
				) );
			}
			if ( empty( $smtp_password ) || ! preg_match( '/^SG\./', $smtp_password ) ) {
				wp_send_json_error( array( 
					'message' => 'SendGrid password should be your API key starting with "SG."' 
				) );
			}
		}

		// Create a temporary PHPMailer instance for testing
		// Handle both old and new PHPMailer versions
		if ( ! class_exists( 'PHPMailer\PHPMailer\PHPMailer' ) ) {
			if ( file_exists( ABSPATH . WPINC . '/PHPMailer/PHPMailer.php' ) ) {
				require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
				require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
				require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
			} else {
				require_once ABSPATH . WPINC . '/class-phpmailer.php';
			}
		}

		// Use the appropriate PHPMailer class
		if ( class_exists( 'PHPMailer\PHPMailer\PHPMailer' ) ) {
			$phpmailer = new PHPMailer\PHPMailer\PHPMailer( true );
		} else {
			$phpmailer = new PHPMailer( true );
		}

		try {
			// Configure SMTP settings
			$phpmailer->isSMTP();
			$phpmailer->Host = $smtp_host;
			$phpmailer->Port = $smtp_port;
			
			if ( ! empty( $smtp_encryption ) ) {
				$phpmailer->SMTPSecure = $smtp_encryption;
			}

			if ( $smtp_auth ) {
				$phpmailer->SMTPAuth = true;
				$phpmailer->Username = $smtp_username;
				$phpmailer->Password = $smtp_password;
			}

			// Additional settings for better compatibility
			$phpmailer->SMTPOptions = array(
				'ssl' => array(
					'verify_peer'       => false,
					'verify_peer_name'  => false,
					'allow_self_signed' => true
				)
			);

			// Set timeout
			$phpmailer->Timeout = 30;
			
			// Enable debug output capture
			$debug_output = '';
			$phpmailer->SMTPDebug = 2;
			$phpmailer->Debugoutput = function( $str, $level ) use ( &$debug_output ) {
				$debug_output .= $str . "\n";
			};

			// Test the connection
			if ( $phpmailer->smtpConnect() ) {
				$phpmailer->smtpClose();
				
				// Try sending a test email
				try {
					$phpmailer->setFrom( $from_email, $from_name );
					$phpmailer->addAddress( $from_email ); // Send to same address for testing
					$phpmailer->Subject = 'SMTP Test - Subscription System';
					$phpmailer->Body = 'This is a test email to verify your SMTP configuration is working correctly.';
					$phpmailer->isHTML( false );

					if ( $phpmailer->send() ) {
						wp_send_json_success( array( 
							'message' => '✅ SMTP connection successful! Test email sent to ' . $from_email 
						) );
					} else {
						wp_send_json_error( array( 
							'message' => 'SMTP connection successful, but failed to send test email: ' . $phpmailer->ErrorInfo . "\n\nDebug output:\n" . $debug_output
						) );
					}
				} catch ( Exception $e ) {
					wp_send_json_error( array( 
						'message' => 'SMTP connection successful, but email sending failed: ' . $e->getMessage() . "\n\nDebug output:\n" . $debug_output
					) );
				} catch ( PHPMailer\PHPMailer\Exception $e ) {
					wp_send_json_error( array( 
						'message' => 'SMTP connection successful, but email sending failed: ' . $e->getMessage() . "\n\nDebug output:\n" . $debug_output
					) );
				}
			} else {
				wp_send_json_error( array( 
					'message' => 'Failed to connect to SMTP server: ' . $phpmailer->ErrorInfo . "\n\nDebug output:\n" . $debug_output
				) );
			}

		} catch ( Exception $e ) {
			wp_send_json_error( array( 
				'message' => 'SMTP Error: ' . $e->getMessage() 
			) );
		} catch ( PHPMailer\PHPMailer\Exception $e ) {
			wp_send_json_error( array( 
				'message' => 'SMTP Error: ' . $e->getMessage() 
			) );
		}
	}

	/**
	 * Get SMTP connection status
	 *
	 * @return array Status information
	 */
	public function get_smtp_status() {
		$status = array(
			'enabled' => get_option( 'subscription_enable_smtp', false ),
			'configured' => false,
			'host' => get_option( 'subscription_smtp_host', '' ),
			'port' => get_option( 'subscription_smtp_port', 587 ),
			'encryption' => get_option( 'subscription_smtp_encryption', '' ),
			'auth' => get_option( 'subscription_smtp_auth', 1 ),
			'username' => get_option( 'subscription_smtp_username', '' )
		);

		// Check if SMTP is properly configured
		if ( $status['enabled'] && ! empty( $status['host'] ) && ! empty( $status['port'] ) ) {
			$status['configured'] = true;
		}

		return $status;
	}

	/**
	 * Log email sending attempt
	 *
	 * @param string $to Recipient email
	 * @param string $subject Email subject
	 * @param bool $success Whether email was sent successfully
	 * @param string $error_message Error message if failed
	 */
	public function log_email_attempt( $to, $subject, $success, $error_message = '' ) {
		$log_message = sprintf(
			'Email %s - To: %s, Subject: %s',
			$success ? 'sent successfully' : 'failed',
			$to,
			$subject
		);

		if ( ! $success && ! empty( $error_message ) ) {
			$log_message .= ', Error: ' . $error_message;
		}

		error_log( 'SMTP Email Log: ' . $log_message );
	}
}

// Initialize the SMTP handler
new Subs_Sys_SMTP();
