<?php

namespace GriffinForms\Includes\Mailer;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

class SmtpMail extends \GriffinForms\Includes\Mailer\Format
{
    // Function to send the email using PHPMailer and SMTP
    public function sendEmail()
    {
        // Ensure WordPress-bundled PHPMailer is loaded
        if (!class_exists('PHPMailer\PHPMailer\PHPMailer')) {
            require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
            require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
            require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        }
        $mail = new \PHPMailer\PHPMailer\PHPMailer(true);  // Use PHPMailer bundled with WordPress Core

        try {
            // Server settings
            $mail->isSMTP();
            $mail->Host = $this->mail_options['smtp_host'];
            $mail->SMTPAuth = true;  // Enable SMTP authentication
            $mail->Username = $this->mail_options['smtp_username'];  // SMTP username
            $mail->Password = $this->mail_options['smtp_password'];  // SMTP password
            $mail->SMTPSecure = $this->mail_options['smtp_encryption'];  // Encryption: tls/ssl
            $mail->Port = $this->mail_options['smtp_port'];  // TCP port to connect to

            // Set sender and recipient
            $mail->setFrom($this->mail_options['sender_email'], $this->mail_options['sender_name']);  // Set the sender's address and name
            $mail->addAddress($this->recipient);  // Add a recipient

            // Set email subject and body content
            $mail->isHTML(true);  // Set email format to HTML
            $mail->Subject = $this->subject;
            $mail->Body = $this->content;

            // Handle headers safely
            if (!empty($this->mail_options['email_headers']) && is_array($this->mail_options['email_headers'])) {
                foreach ($this->mail_options['email_headers'] as $header) {
                    $header_parts = explode(':', $header, 2);
                    if (count($header_parts) === 2) {
                        $header_name = trim($header_parts[0]);
                        $header_value = trim($header_parts[1]);

                        // Handle reserved headers with the appropriate PHPMailer methods
                        if (strcasecmp($header_name, 'Reply-To') === 0) {
                            $mail->addReplyTo($header_value);
                        } elseif (strcasecmp($header_name, 'CC') === 0) {
                            $mail->addCC($header_value);
                        } elseif (strcasecmp($header_name, 'BCC') === 0) {
                            $mail->addBCC($header_value);
                        } else {
                            // Add other non-reserved headers
                            $mail->addCustomHeader($header_name, $header_value);
                        }
                    }
                }
            }

            // Send the email
            $mail->send();
            // Log success
            if (isset($this->log) && is_object($this->log)) {
                if ($this->submission_id > 0) {
                    $this->setLogContext('submission', $this->submission_id);
                }
                $this->log->add(
                    'info',
                    $this->log_item_type,
                    $this->log_item_id,
                    get_current_user_id(),
                    sprintf(__('SMTP email successfully sent (%s)', 'griffinforms-form-builder'), $this->getRecipientDescriptor()),
                    $this->getLogCategory()
                );
            }
            return true;

        } catch (Exception $e) {
            // Log error
            if (isset($this->log) && is_object($this->log)) {
                if ($this->submission_id > 0) {
                    $this->setLogContext('submission', $this->submission_id);
                }
                $this->log->add(
                    'error',
                    $this->log_item_type,
                    $this->log_item_id,
                    get_current_user_id(),
                    sprintf(__('SMTP email failed (%1$s): %2$s', 'griffinforms-form-builder'), $this->getRecipientDescriptor(), $mail->ErrorInfo),
                    $this->getLogCategory()
                );
            }
            // Return WP_Error if email fails
            return new \WP_Error('email_failed', __('The email could not be sent. PHPMailer error: ', 'griffinforms-form-builder') . $mail->ErrorInfo);
        }
    }
}
