<?php declare(strict_types=1);
// Christo Lochenberg Developments | info@christodev.co.za | +27 61 523 9126

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

// Zero-Breakage: Safely check if PHPMailer files exist before requiring them.
$exceptionPath = APPROOT . '/app/Libraries/PHPMailer/src/Exception.php';
$phpmailerPath = APPROOT . '/app/Libraries/PHPMailer/src/PHPMailer.php';
$smtpPath      = APPROOT . '/app/Libraries/PHPMailer/src/SMTP.php';

// Check local libraries first, fallback to composer vendor autoload if it was loaded in public/index.php
if (file_exists($exceptionPath) && file_exists($phpmailerPath) && file_exists($smtpPath)) {
    require_once $exceptionPath;
    require_once $phpmailerPath;
    require_once $smtpPath;
} elseif (!class_exists('PHPMailer\PHPMailer\PHPMailer')) {
    error_log("CRITICAL: PHPMailer Library Missing. The system expects the file to be in app/Libraries/PHPMailer or loaded via Composer.");
}

/**
 * Global helper to queue emails into the database using a global HTML Card Template
 */
function sendEmail($to, string $subject, string $body, array $attachments = []): bool {
    $db = new Database();
    $settings = getSettings();
    
    // FIX: Use !empty instead of the null coalescing operator (??).
    // If the database has an empty string ("") saved, ?? will accept it instead of falling back to SITENAME.
    $appName = !empty($settings['app_name']) ? $settings['app_name'] : SITENAME;
    
    $year = date('Y');
    $appUrl = URLROOT;
    $loginUrl = URLROOT . '/users/login';
    
    // Header Logo Processing (Base64 Embedding & Strict Width Enforcement)
    $headerContent = '';

    if (!empty($settings['logo_light'])) {
        $logoPath = APPROOT . '/public/uploads/' . $settings['logo_light'];
        
        if (file_exists($logoPath)) {
            $mimeType = 'image/png'; // Default
            $imgSize = @getimagesize($logoPath);
            
            if ($imgSize !== false && isset($imgSize['mime'])) {
                $mimeType = $imgSize['mime'];
            } else {
                $ext = strtolower(pathinfo($logoPath, PATHINFO_EXTENSION));
                if ($ext === 'jpg' || $ext === 'jpeg') $mimeType = 'image/jpeg';
                elseif ($ext === 'gif') $mimeType = 'image/gif';
                elseif ($ext === 'webp') $mimeType = 'image/webp';
                elseif ($ext === 'svg') $mimeType = 'image/svg+xml';
            }

            $base64Data = base64_encode(file_get_contents($logoPath));
            $imgSrc = 'data:' . $mimeType . ';base64,' . $base64Data;
            
            $imgWidth = 300;
            if ($imgSize && isset($imgSize[0]) && $imgSize[0] < 300) {
                $imgWidth = $imgSize[0]; 
            }

            // Inline styles for height: auto guarantee aspect ratio maintenance across email clients
            $headerContent = '<img src="' . $imgSrc . '" alt="' . htmlspecialchars($appName) . '" width="' . $imgWidth . '" style="width: 100%; max-width: 300px; height: auto; display: block; margin: 0 auto; border: 0;">';
        } else {
            $headerContent = '<h1 style="margin: 0; color: #1c70b4; font-size: 24px; text-align: center; font-family: \'Plus Jakarta Sans\', Arial, sans-serif; font-weight: 800;">' . htmlspecialchars($appName) . '</h1>';
        }
    } else {
        $headerContent = '<h1 style="margin: 0; color: #1c70b4; font-size: 24px; text-align: center; font-family: \'Plus Jakarta Sans\', Arial, sans-serif; font-weight: 800;">' . htmlspecialchars($appName) . '</h1>';
    }

    // Email HTML Shell (Styled to match the SaaS Tailwind Palette)
    $htmlTemplate = <<<HTML
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{$subject}</title>
        <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
        <style>
            body, table, td, p, a, h1, h2, h3, h4, h5, h6 {
                font-family: 'Plus Jakarta Sans', Arial, Helvetica, sans-serif;
            }
        </style>
    </head>
    <body style="margin: 0; padding: 0; background-color: #f1f5f9; font-family: 'Plus Jakarta Sans', Arial, Helvetica, sans-serif; -webkit-font-smoothing: antialiased;">
        <table width="100%" cellpadding="0" cellspacing="0" style="background-color: #f1f5f9; padding: 40px 20px; width: 100%;">
            <tr>
                <td align="center">
                    <table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; background-color: #ffffff; border: 1px solid #e2e8f0; border-radius: 12px; overflow: hidden; width: 100%; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);">
                        <tr>
                            <td align="center" style="padding: 30px 20px; border-bottom: 1px solid #e2e8f0; background-color: #f8fafc;">
                                {$headerContent}
                            </td>
                        </tr>
                        <tr>
                            <td style="padding: 40px 30px; color: #334155; font-size: 15px; line-height: 1.6;">
                                {$body}
                            </td>
                        </tr>
                        <tr>
                            <td align="center" style="padding: 24px 20px; border-top: 1px solid #e2e8f0; background-color: #f8fafc; font-size: 12px; color: #64748b; line-height: 1.5;">
                                <a href="{$loginUrl}" style="color: #64748b; text-decoration: underline; font-weight: 600;">Securely Login to Portal</a>
                            </td>
                        </tr>
                    </table>
                    
                    <table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; width: 100%;">
                        <tr>
                            <td align="center" style="padding: 24px 20px 12px 20px; font-size: 10px; color: #94a3b8; line-height: 1.6; text-align: center;">
                                This email and any attachments are confidential and intended solely for the recipient. If you received this in error, please notify the sender immediately and delete all copies. Any views expressed are those of the individual and not necessarily the organization. No binding contract is formed via email unless explicitly stated. Electronic communication is not guaranteed to be secure or error-free.
                            </td>
                        </tr>
                        <tr>
                            <td align="center" style="font-size: 11px; color: #94a3b8; line-height: 1.5;">
                                &copy; {$year} <a href="{$appUrl}" target="_blank" style="color: #94a3b8; text-decoration: underline; font-weight: bold;">{$appName}</a>. All Rights Reserved.
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </body>
    </html>
HTML;

    $encodedAttachments = json_encode($attachments);
    $recipients = is_array($to) ? $to : [$to];
    $success = true;

    foreach ($recipients as $email) {
        $db->query("INSERT INTO email_queue (recipient_email, subject, body, attachments, status) VALUES (:email, :subject, :body, :attachments, 'pending')");
        $db->bind(':email', $email);
        $db->bind(':subject', $subject);
        $db->bind(':body', $htmlTemplate);
        $db->bind(':attachments', $encodedAttachments);
        
        if (!$db->execute()) {
            $success = false;
        }
    }

    return $success;
}

/**
 * Triggered by Cron. Processes the email queue and sends via SMTP.
 */
function processEmailQueue(int $limit = 30): int {
    $db = new Database();
    $settings = getSettings();

    if (!class_exists('PHPMailer\PHPMailer\PHPMailer')) {
        error_log("Mail Error: PHPMailer classes not loaded during queue processing.");
        return 0;
    }

    $db->query("SELECT * FROM email_queue WHERE status = 'pending' ORDER BY created_at ASC LIMIT :limit");
    $db->bind(':limit', $limit);
    $emails = $db->resultSet();

    if (empty($emails)) {
        return 0;
    }

    $mail = new PHPMailer(true);
    $sentCount = 0;

    try {
        $mail->isSMTP();
        $mail->Host       = $settings['smtp_host'] ?? '';
        $mail->SMTPAuth   = true;
        $mail->Username   = $settings['smtp_user'] ?? '';
        $mail->Password   = $settings['smtp_pass'] ?? '';
        $mail->Port       = (int)($settings['smtp_port'] ?? 465);
        $mail->SMTPKeepAlive = true; 
        
        // Handle Encryption Protocol Selection
        $encryption = $settings['smtp_encryption'] ?? 'ssl';
        if ($encryption === 'ssl') {
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
        } elseif ($encryption === 'tls') {
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        } else {
            $mail->SMTPAutoTLS = false;
            $mail->SMTPSecure = '';
        }
        
        $mail->SMTPOptions = array(
            'ssl' => array(
                'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
            )
        );

        $fromEmail = $settings['smtp_from_email'] ?? 'noreply@domain.com';
        $fromName  = $settings['smtp_from_name'] ?? SITENAME;

        foreach ($emails as $emailJob) {
            try {
                $mail->clearAllRecipients();
                $mail->clearAttachments();
                $mail->clearBCCs();

                $mail->setFrom($fromEmail, $fromName);
                $mail->addAddress($emailJob->recipient_email);

                // Global BCC Logic
                if (isset($settings['smtp_bcc_enable']) && $settings['smtp_bcc_enable'] === '1' && !empty($settings['smtp_bcc_email'])) {
                    $mail->addBCC($settings['smtp_bcc_email']);
                }

                $attachments = json_decode($emailJob->attachments, true);
                if (is_array($attachments)) {
                    foreach ($attachments as $filePath) {
                        if (file_exists($filePath)) {
                            $mail->addAttachment($filePath);
                        }
                    }
                }

                $mail->isHTML(true);
                $mail->Subject = $emailJob->subject;
                $mail->Body    = $emailJob->body;
                $mail->AltBody = strip_tags(str_replace(['<br>', '<br/>', '</p>'], "\n", $emailJob->body));

                $mail->send();

                $db->query("UPDATE email_queue SET status = 'sent', sent_at = NOW() WHERE id = :id");
                $db->bind(':id', $emailJob->id);
                $db->execute();
                
                $sentCount++;

                if (is_array($attachments)) {
                    foreach ($attachments as $filePath) {
                        if (file_exists($filePath) && strpos($filePath, 'temp_support') !== false) {
                            // Only delete the file if no other pending emails need this exact attachment
                            $db->query("SELECT COUNT(*) as count FROM email_queue WHERE status = 'pending' AND attachments LIKE :filename");
                            $db->bind(':filename', '%' . basename($filePath) . '%');
                            $pendingQueueRecord = $db->single();
                            
                            if ($pendingQueueRecord && (int)$pendingQueueRecord->count === 0) {
                                @unlink($filePath);
                            }
                        }
                    }
                }

            } catch (Exception $e) {
                $db->query("UPDATE email_queue SET status = 'failed', error_message = :error WHERE id = :id");
                $db->bind(':id', $emailJob->id);
                $db->bind(':error', $mail->ErrorInfo);
                $db->execute();
            }
        }

        $mail->smtpClose();

    } catch (Exception $e) {
        error_log("Critical Mailer Error in Queue: " . $e->getMessage());
    }

    return $sentCount;
}