<?php
$phpmailerPath = __DIR__ . '/../vendor/phpmailer/phpmailer/src/PHPMailer.php';
$smtpPath = __DIR__ . '/../vendor/phpmailer/phpmailer/src/SMTP.php';
$exceptionPath = __DIR__ . '/../vendor/phpmailer/phpmailer/src/Exception.php';

if (!file_exists($phpmailerPath)) {
    throw new Exception("PHPMailer not found at: $phpmailerPath - Please extract PHPMailer to vendor/phpmailer/phpmailer/src/");
}

require_once $phpmailerPath;
require_once $smtpPath;
require_once $exceptionPath;

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

require_once 'Logger.php';

class EmailService {
    private $conn;
    private $logger;
    private $smtpConfig;

    public function __construct($conn, $logger = null) {
        $this->conn = $conn;
        $this->logger = $logger;
        $this->loadSmtpConfig();
    }

    private function loadSmtpConfig() {
        $settings = $this->getBackupSettings([
            'smtp_host', 'smtp_port', 'smtp_username', 'smtp_password',
            'smtp_encryption', 'admin_email'
        ]);

        $this->smtpConfig = [
            'host' => $settings['smtp_host'] ?? '',
            'port' => (int)($settings['smtp_port'] ?? 587),
            'username' => $settings['smtp_username'] ?? '',
            'password' => $this->decryptPassword($settings['smtp_password'] ?? ''),
            'encryption' => $settings['smtp_encryption'] ?? 'tls',
            'admin_email' => $settings['admin_email'] ?? ''
        ];
        
        error_log("SMTP Config loaded: " . json_encode([
            'host' => $this->smtpConfig['host'],
            'port' => $this->smtpConfig['port'],
            'username' => $this->smtpConfig['username'],
            'password' => !empty($this->smtpConfig['password']) ? '[SET]' : '[EMPTY]',
            'encryption' => $this->smtpConfig['encryption'],
            'admin_email' => $this->smtpConfig['admin_email']
        ]));
    }

    private function getBackupSettings($keys) {
        $placeholders = str_repeat('?,', count($keys) - 1) . '?';
        $sql = "SELECT setting_key, setting_value, is_encrypted
                FROM backup_settings
                WHERE setting_key IN ($placeholders)";

        try {
            $stmt = $this->conn->prepare($sql);
            $stmt->execute($keys);
            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $settings = [];
            foreach ($results as $result) {
                $settings[$result['setting_key']] = $result['setting_value'];
            }
            
            error_log("Retrieved settings from DB: " . json_encode($settings));

            return $settings;
        } catch (Exception $e) {
            error_log("Error getting backup settings: " . $e->getMessage());
            return [];
        }
    }

    private function decryptPassword($encryptedPassword) {
        return $encryptedPassword;
    }

    public function sendBackupEmail($backupId, $filePath, $backupType = 'full') {
        try {
            if (empty($this->smtpConfig['admin_email'])) {
                throw new Exception("Admin email address not configured");
            }

            if (!file_exists($filePath)) {
                throw new Exception("Backup file not found: $filePath");
            }

            $backupDetails = $this->getBackupDetails($backupId);
            $subject = $this->generateEmailSubject($backupType, $backupDetails);
            $body = $this->generateEmailBody($backupType, $backupDetails);
            $attachment = $this->prepareAttachment($filePath);

            $result = $this->sendSmtpEmail(
                $this->smtpConfig['admin_email'],
                $subject,
                $body,
                $attachment
            );

            if ($result) {
                $this->updateEmailStatus($backupId, true);
                $this->logEmailSuccess($backupId, $filePath);
                return true;
            } else {
                throw new Exception("Failed to send email via SMTP.");
            }

        } catch (Exception $e) {
            $this->updateEmailStatus($backupId, false, $e->getMessage());
            $this->logEmailFailure($backupId, $e->getMessage());
            throw $e;
        }
    }

    private function getBackupDetails($backupId) {
        $sql = "SELECT bh.*, u.username as created_by_name,
                        COUNT(bf.file_id) as file_count,
                        SUM(bf.record_count) as total_records
                FROM backup_history bh
                LEFT JOIN users u ON bh.created_by = u.user_id
                LEFT JOIN backup_files bf ON bh.backup_id = bf.backup_id
                WHERE bh.backup_id = :backup_id
                GROUP BY bh.backup_id";

        $stmt = $this->conn->prepare($sql);
        $stmt->bindValue(':backup_id', $backupId, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    private function generateEmailSubject($backupType, $backupDetails) {
        $date = date('Y-m-d', strtotime($backupDetails['backup_date']));
        $typeLabel = ucfirst(str_replace('_', ' ', $backupType));
        return "IMS {$typeLabel} Backup - {$date} (ID: {$backupDetails['backup_id']})";
    }

    private function generateEmailBody($backupType, $backupDetails) {
        $date = date('F j, Y \a\t g:i A', strtotime($backupDetails['backup_date']));
        $fileSize = $this->formatFileSize($backupDetails['file_size']);
        $executionTime = $backupDetails['execution_time'];

        return "
        <html>
        <head>
            <style>
                body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
                .header { background: #f8f9fa; padding: 20px; border-radius: 5px; margin-bottom: 20px; }
                .details { background: #e9ecef; padding: 15px; border-radius: 5px; margin: 10px 0; }
                .success { color: #28a745; font-weight: bold; }
                .footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #dee2e6; font-size: 12px; color: #6c757d; }
            </style>
        </head>
        <body>
            <div class='header'>
                <h2>📧 Inventory Management System Backup</h2>
                <p>Automated backup has been completed successfully.</p>
            </div>
            <div class='details'>
                <h3>Backup Details</h3>
                <ul>
                    <li><strong>Backup ID:</strong> {$backupDetails['backup_id']}</li>
                    <li><strong>Type:</strong> " . ucfirst(str_replace('_', ' ', $backupType)) . "</li>
                    <li><strong>Date:</strong> {$date}</li>
                    <li><strong>Status:</strong> <span class='success'>✅ Completed Successfully</span></li>
                    <li><strong>File Size:</strong> {$fileSize}</li>
                    <li><strong>Execution Time:</strong> {$executionTime} seconds</li>
                    <li><strong>Files Included:</strong> {$backupDetails['file_count']}</li>
                    <li><strong>Total Records:</strong> " . number_format($backupDetails['total_records']) . "</li>
                </ul>
            </div>
            <div class='footer'>
                <p><strong>Important:</strong> This backup contains sensitive business data. Please store securely.</p>
                <p>This is an automated message from the Inventory Management System. Please do not reply.</p>
            </div>
        </body>
        </html>";
    }

    private function prepareAttachment($filePath) {
        return [
            'path' => $filePath,
            'name' => basename($filePath),
            'type' => 'application/zip'
        ];
    }

    private function sendSmtpEmail($to, $subject, $body, $attachment = null) {
        if (empty($this->smtpConfig['host']) || empty($this->smtpConfig['username'])) {
            throw new Exception("SMTP configuration is incomplete. Please save settings first.");
        }

        $mail = new PHPMailer(true);

        try {
            $mail = new PHPMailer(true);

            $mail->isSMTP();
            $mail->Host       = $this->smtpConfig['host'];
            $mail->SMTPAuth   = true;
            $mail->Username   = $this->smtpConfig['username'];
            $mail->Password   = $this->smtpConfig['password'];
            $mail->SMTPSecure = $this->smtpConfig['encryption'] === 'none' ? false : $this->smtpConfig['encryption'];
            $mail->Port       = (int)$this->smtpConfig['port'];

            $mail->setFrom($this->smtpConfig['username'], 'IMS Backup System');
            $mail->addAddress($to);
            $mail->addReplyTo($this->smtpConfig['username'], 'Information');

            if ($attachment && file_exists($attachment['path'])) {
                $mail->addAttachment($attachment['path'], $attachment['name']);
            }

            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body    = $body;
            $mail->AltBody = 'Please use an HTML-compatible email client to view this message.';

            return $mail->send();
        } catch (Exception $e) {
            throw new Exception("Message could not be sent. Mailer Error: {$mail->ErrorInfo}");
        }
    }

    private function updateEmailStatus($backupId, $success, $errorMessage = null) {
        $sql = "UPDATE backup_history SET
                email_sent = :email_sent,
                email_sent_at = " . ($success ? "NOW()" : "NULL") . ",
                admin_notified = :admin_notified";

        if ($errorMessage) {
            $sql .= ", error_message = CONCAT(IFNULL(error_message, ''), ' Email error: " . $this->conn->quote($errorMessage) . "')";
        }

        $sql .= " WHERE backup_id = :backup_id";

        $stmt = $this->conn->prepare($sql);
        $stmt->bindValue(':email_sent', $success, PDO::PARAM_BOOL);
        $stmt->bindValue(':admin_notified', $success, PDO::PARAM_BOOL);
        $stmt->bindValue(':backup_id', $backupId, PDO::PARAM_INT);
        $stmt->execute();
    }

    public function sendFailureNotification($backupId, $errorMessage) {
        try {
            if (empty($this->smtpConfig['admin_email'])) {
                return false;
            }

            $subject = "🚨 IMS Backup Failed - ID: {$backupId}";
            $body = "
            <html><body>
                <h2 style='color: #dc3545;'>Backup Failure Alert</h2>
                <p>A backup operation has failed and requires attention.</p>
                <div style='background: #f8d7da; padding: 15px; border-radius: 5px;'>
                    <h3>Failure Details</h3>
                    <ul>
                        <li><strong>Backup ID:</strong> {$backupId}</li>
                        <li><strong>Attempted:</strong> " . date('F j, Y \a\t g:i A') . "</li>
                        <li><strong>Error:</strong> {$errorMessage}</li>
                    </ul>
                </div>
                <p>Please check the system logs and resolve the issue.</p>
            </body></html>";

            return $this->sendSmtpEmail($this->smtpConfig['admin_email'], $subject, $body);

        } catch (Exception $e) {
            error_log("Failed to send failure notification: " . $e->getMessage());
            return false;
        }
    }

    public function sendTestEmail($to = null) {
        $this->loadSmtpConfig();
        
        $recipient = $to ?: $this->smtpConfig['admin_email'];

        if (empty($recipient)) {
            throw new Exception("No email address configured for testing.");
        }
        
        if (empty($this->smtpConfig['host']) || empty($this->smtpConfig['username'])) {
            throw new Exception("SMTP configuration is incomplete. Host: '{$this->smtpConfig['host']}', Username: '{$this->smtpConfig['username']}'");
        }

        $subject = "🧪 IMS Backup System - Test Email";
        $body = "
        <html><body>
            <h2 style='color: #28a745;'>Test Email Successful</h2>
            <p>The backup email system is working correctly!</p>
            <div style='background: #d4edda; padding: 15px; border-radius: 5px;'>
                <h3>Configuration Details</h3>
                <ul>
                    <li><strong>SMTP Host:</strong> {$this->smtpConfig['host']}</li>
                    <li><strong>SMTP Port:</strong> {$this->smtpConfig['port']}</li>
                    <li><strong>Username:</strong> {$this->smtpConfig['username']}</li>
                    <li><strong>Encryption:</strong> " . strtoupper($this->smtpConfig['encryption']) . "</li>
                </ul>
            </div>
            <p><strong>Sent at:</strong> " . date('Y-m-d H:i:s') . "</p>
        </body></html>";

        return $this->sendSmtpEmail($recipient, $subject, $body);
    }

    private function formatFileSize($bytes) {
        if (!$bytes) return '0 B';
        $units = ['B', 'KB', 'MB', 'GB'];
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        $bytes /= pow(1024, $pow);
        return round($bytes, 2) . ' ' . $units[$pow];
    }

    private function logEmailSuccess($backupId, $filePath) {
        if ($this->logger) {
            $this->logger->log('BACKUP_EMAIL_SENT', 'backup_system',
                "Backup email sent for backup ID: $backupId, file: " . basename($filePath),
                $backupId, 'backup_history');
        }
    }

    private function logEmailFailure($backupId, $errorMessage) {
        if ($this->logger) {
            $this->logger->log('BACKUP_EMAIL_FAILED', 'backup_system',
                "Backup email failed for backup ID: $backupId - Error: $errorMessage",
                $backupId, 'backup_history');
        }
    }

    public function getSmtpConfig() {
        return [
            'host' => $this->smtpConfig['host'],
            'port' => $this->smtpConfig['port'],
            'username' => $this->smtpConfig['username'],
            'encryption' => $this->smtpConfig['encryption'],
            'admin_email' => $this->smtpConfig['admin_email']
        ];
    }
}
?>