<?php
// Don't include config.php here as it's already included by the calling file

class EmailSender {
    private $pdo;
    private $settings;
    
    public function __construct($pdo) {
        $this->pdo = $pdo;
        $this->loadSettings();
    }
    
    private function loadSettings() {
        $stmt = $this->pdo->prepare("SELECT setting_name, setting_value FROM smtp_settings WHERE is_active = 1");
        $stmt->execute();
        $this->settings = [];
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $this->settings[$row['setting_name']] = $row['setting_value'];
        }
    }
    
    public function sendMessage($to_email, $subject, $message, $template_id = null, $booking_id = null, $from_name_override = null) {
        try {
            // Debug logging
            error_log("Email sendMessage called with: to_email=$to_email, subject_length=" . strlen($subject));
            
            // Validate inputs
            if (empty($to_email)) {
                throw new Exception('Email address is required');
            }
            if (empty($subject)) {
                throw new Exception('Subject is required');
            }
            if (empty($message)) {
                throw new Exception('Message is required');
            }
            
            // Validate email format
            if (!filter_var($to_email, FILTER_VALIDATE_EMAIL)) {
                throw new Exception('Invalid email address format');
            }
            
            // Validate settings
            if (empty($this->settings['smtp_host'])) {
                throw new Exception('SMTP Host not configured');
            }
            if (empty($this->settings['smtp_username'])) {
                throw new Exception('SMTP Username not configured');
            }
            if (empty($this->settings['smtp_password'])) {
                throw new Exception('SMTP Password not configured');
            }
            
            // Log message before sending
            $log_id = $this->logMessage($to_email, $subject, $message, $template_id, $booking_id);
            
            // Send message via SMTP
            $smtp_response = $this->sendEmailViaSMTP($to_email, $subject, $message, $from_name_override);
            
            // Update log with response
            $this->updateMessageLog($log_id, $smtp_response);
            
            return [
                'status' => 'success',
                'message' => 'Email sent successfully',
                'log_id' => $log_id,
                'smtp_response' => $smtp_response
            ];
            
        } catch (Exception $e) {
            error_log("Email sendMessage error: " . $e->getMessage());
            // Log error
            if (isset($log_id)) {
                $this->updateMessageLog($log_id, null, 'failed', $e->getMessage());
            }
            
            return [
                'status' => 'error',
                'message' => $e->getMessage()
            ];
        }
    }
    
    private function sendEmailViaSMTP($to_email, $subject, $message, $from_name_override = null) {
        // Get SMTP settings
        $smtp_host = $this->settings['smtp_host'] ?? '';
        $smtp_port = (int)($this->settings['smtp_port'] ?? 587);
        $smtp_username = $this->settings['smtp_username'] ?? '';
        $smtp_password = $this->settings['smtp_password'] ?? '';
        $smtp_encryption = $this->settings['smtp_encryption'] ?? 'tls';
        $from_email = $this->settings['from_email'] ?? $smtp_username;
        $from_name = $from_name_override ?: ($this->settings['from_name'] ?? 'Controller Of Examination');
        
        // Validate required settings
        if (empty($smtp_host) || empty($smtp_username) || empty($smtp_password)) {
            throw new Exception('SMTP configuration incomplete');
        }
        
        // Create email content
        $email_content = $this->createEmailContent($message, $from_name_override);
        
        // Send email using proper SMTP connection
        $smtp_response = $this->sendEmailWithSMTP($smtp_host, $smtp_port, $smtp_username, $smtp_password, $smtp_encryption, $from_email, $from_name, $to_email, $subject, $email_content);
        
        return [
            'smtp_host' => $smtp_host,
            'smtp_port' => $smtp_port,
            'smtp_username' => $smtp_username,
            'from_email' => $from_email,
            'to_email' => $to_email,
            'subject' => $subject,
            'response' => $smtp_response
        ];
    }
    
    private function sendEmailWithSMTP($host, $port, $username, $password, $encryption, $from, $from_name, $to, $subject, $message) {
        // Use PHPMailer if available, otherwise use a simple SMTP implementation
        if (class_exists('PHPMailer\PHPMailer\PHPMailer')) {
            error_log("Using PHPMailer for email sending");
            return $this->sendWithPHPMailer($host, $port, $username, $password, $encryption, $from, $from_name, $to, $subject, $message);
        } else {
            error_log("PHPMailer not available, using simple SMTP implementation");
            return $this->sendWithSimpleSMTP($host, $port, $username, $password, $encryption, $from, $from_name, $to, $subject, $message);
        }
    }
    
    private function sendWithPHPMailer($host, $port, $username, $password, $encryption, $from, $from_name, $to, $subject, $message) {
        try {
            $mail = new PHPMailer\PHPMailer\PHPMailer(true);
            
            // Server settings
            $mail->isSMTP();
            $mail->Host = $host;
            $mail->SMTPAuth = true;
            $mail->Username = $username;
            $mail->Password = $password;
            $mail->SMTPSecure = $encryption;
            $mail->Port = $port;
            $mail->SMTPDebug = 0; // Set to 2 for debugging
            $mail->Timeout = 30; // 30 seconds timeout
            
            // Additional settings for better compatibility
            $mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                )
            );
            
            // Recipients
            $mail->setFrom($from, $from_name);
            $mail->addAddress($to);
            
            // Content
            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body = $message;
            $mail->CharSet = 'UTF-8';
            
            error_log("PHPMailer: Attempting to send email to $to via $host:$port");
            $mail->send();
            error_log("PHPMailer: Email sent successfully to $to");
            
            return 'Email sent successfully via PHPMailer';
            
        } catch (Exception $e) {
            error_log("PHPMailer Error: " . $e->getMessage());
            throw new Exception('PHPMailer Error: ' . $e->getMessage());
        }
    }
    
    private function sendWithSimpleSMTP($host, $port, $username, $password, $encryption, $from, $from_name, $to, $subject, $message) {
        // Create a simple SMTP connection using fsockopen
        $timeout = 30;
        $errno = 0;
        $errstr = '';
        
        // Connect to SMTP server
        $connection = @fsockopen($host, $port, $errno, $errstr, $timeout);
        
        if (!$connection) {
            throw new Exception("Failed to connect to SMTP server: $errstr (Error $errno)");
        }
        
        try {
            // Read server greeting
            $response = fgets($connection, 515);
            if (!$response || !preg_match('/^220/', $response)) {
                throw new Exception("SMTP server not ready: " . trim($response));
            }
            
            // Send EHLO
            fputs($connection, "EHLO " . $_SERVER['HTTP_HOST'] . "\r\n");
            $response = fgets($connection, 515);
            
            // Start TLS if required
            if (strtolower($encryption) === 'tls') {
                fputs($connection, "STARTTLS\r\n");
                $response = fgets($connection, 515);
                if (!preg_match('/^220/', $response)) {
                    throw new Exception("STARTTLS failed: " . trim($response));
                }
                
                // Enable crypto
                if (!stream_socket_enable_crypto($connection, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
                    throw new Exception("TLS negotiation failed");
                }
                
                // Send EHLO again after TLS
                fputs($connection, "EHLO " . $_SERVER['HTTP_HOST'] . "\r\n");
                $response = fgets($connection, 515);
            }
            
            // Authenticate
            fputs($connection, "AUTH LOGIN\r\n");
            $response = fgets($connection, 515);
            if (!preg_match('/^334/', $response)) {
                throw new Exception("AUTH LOGIN not supported: " . trim($response));
            }
            
            fputs($connection, base64_encode($username) . "\r\n");
            $response = fgets($connection, 515);
            if (!preg_match('/^334/', $response)) {
                throw new Exception("Username rejected: " . trim($response));
            }
            
            fputs($connection, base64_encode($password) . "\r\n");
            $response = fgets($connection, 515);
            if (!preg_match('/^235/', $response)) {
                throw new Exception("Authentication failed: " . trim($response));
            }
            
            // Send MAIL FROM
            fputs($connection, "MAIL FROM: <$from>\r\n");
            $response = fgets($connection, 515);
            if (!preg_match('/^250/', $response)) {
                throw new Exception("MAIL FROM failed: " . trim($response));
            }
            
            // Send RCPT TO
            fputs($connection, "RCPT TO: <$to>\r\n");
            $response = fgets($connection, 515);
            if (!preg_match('/^250/', $response)) {
                throw new Exception("RCPT TO failed: " . trim($response));
            }
            
            // Send DATA
            fputs($connection, "DATA\r\n");
            $response = fgets($connection, 515);
            if (!preg_match('/^354/', $response)) {
                throw new Exception("DATA command failed: " . trim($response));
            }
            
            // Prepare email headers
            $headers = [
                "From: $from_name <$from>",
                "To: $to",
                "Subject: $subject",
                "MIME-Version: 1.0",
                "Content-Type: text/html; charset=UTF-8",
                "X-Mailer: PHP/" . phpversion()
            ];
            
            $email_data = implode("\r\n", $headers) . "\r\n\r\n" . $message . "\r\n.\r\n";
            
            // Send email data
            fputs($connection, $email_data);
            $response = fgets($connection, 515);
            if (!preg_match('/^250/', $response)) {
                throw new Exception("Email sending failed: " . trim($response));
            }
            
            // Quit
            fputs($connection, "QUIT\r\n");
            fclose($connection);
            
            return 'Email sent successfully via SMTP';
            
        } catch (Exception $e) {
            if ($connection) {
                fclose($connection);
            }
            throw $e;
        }
    }
    
    private function createEmailContent($message, $brand_override = null) {
        // Use configured name as heading; fall back to a sensible default
        $brand = $brand_override ?: ($this->settings['from_name'] ?? 'Controller Of Examination');
        // Treat $message as HTML (callers often pass HTML with links); do not escape
        $bodyHtml = (string)$message;

        $html = '<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>' . htmlspecialchars($brand) . '</title>
  <style>
    @media screen { body { background:#f3f4f6; margin:0; padding:0; } }
    .wrapper{width:100%; background:#f3f4f6; padding:20px 0;}
    .container{max-width:640px; margin:0 auto; background:#ffffff; border-radius:8px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,0.06);} 
    .header{background:#0d6efd; color:#ffffff; padding:18px 22px; text-align:center;}
    .brand{margin:0; font-size:18px; letter-spacing:.3px;}
    .sub{margin:2px 0 0; font-size:12px; opacity:.9;}
    .content{padding:22px; color:#111827; font-family:Arial,Helvetica,sans-serif; line-height:1.6;}
    .content a{color:#0d6efd; text-decoration:none;}
    .card{border:1px solid #e5e7eb; border-radius:8px; padding:14px 16px; background:#fafafa;}
    .btn{display:inline-block; background:#0d6efd; color:#ffffff !important; padding:10px 16px; border-radius:6px; text-decoration:none; margin:8px 0;}
    .footer{padding:14px 22px; text-align:center; color:#6b7280; font-size:12px;}
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="container">
      <div class="header">
        <h1 class="brand">' . htmlspecialchars($brand) . '</h1>
        <div class="sub">Official Communication</div>
      </div>
      <div class="content">'
        . $bodyHtml .
      '</div>
      <div class="footer">
        <div>This is an automated email. Please do not reply.</div>
      </div>
    </div>
  </div>
 </body>
 </html>';
        return $html;
    }
    
    private function logMessage($to_email, $subject, $message, $template_id = null, $booking_id = null) {
        $stmt = $this->pdo->prepare("INSERT INTO email_message_logs (booking_id, template_id, to_email, subject, message_content, status, created_by) VALUES (?, ?, ?, ?, ?, 'pending', ?)");
        $stmt->execute([$booking_id, $template_id, $to_email, $subject, $message, $_SESSION['user_id'] ?? null]);
        return $this->pdo->lastInsertId();
    }
    
    private function updateMessageLog($log_id, $smtp_response = null, $status = 'sent', $error_message = null) {
        $stmt = $this->pdo->prepare("UPDATE email_message_logs SET smtp_response = ?, status = ?, error_message = ?, delivered_at = ? WHERE id = ?");
        $delivered_at = ($status === 'delivered') ? date('Y-m-d H:i:s') : null;
        $stmt->execute([json_encode($smtp_response), $status, $error_message, $delivered_at, $log_id]);
    }
    
    public function sendBookingEmail($booking_id, $template_type = 'booking_created') {
        try {
            error_log("Email sendBookingEmail called with: booking_id=$booking_id, template_type=$template_type");
            
            // Get booking details
            $stmt = $this->pdo->prepare("SELECT * FROM booking WHERE id = ?");
            $stmt->execute([$booking_id]);
            $booking = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$booking) {
                throw new Exception('Booking not found');
            }
            
            error_log("Booking found: consignee_email=" . ($booking['consignee_email'] ?? 'N/A'));
            
            // Get template
            $stmt = $this->pdo->prepare("SELECT * FROM email_message_templates WHERE template_type = ? AND is_active = 1 ORDER BY id ASC LIMIT 1");
            $stmt->execute([$template_type]);
            $template = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$template) {
                throw new Exception("No active template found for type: $template_type");
            }
            
            error_log("Template found: " . $template['template_name']);
            
            // Prepare message variables
            $variables = $this->prepareBookingVariables($booking);
            error_log("Variables prepared: " . json_encode($variables));
            
            // Replace variables in template
            $subject = $this->replaceTemplateVariables($template['subject_template'], $variables);
            $message = $this->replaceTemplateVariables($template['message_template'], $variables);
            error_log("Message prepared: " . substr($message, 0, 100) . "...");
            
            // Get recipient email (use consignee email if available, otherwise use a default)
            $to_email = $booking['consignee_email'] ?? $this->settings['from_email'] ?? 'admin@example.com';
            
            // Validate email address
            if (empty($to_email) || !filter_var($to_email, FILTER_VALIDATE_EMAIL)) {
                throw new Exception('Invalid or missing consignee email address. Please provide a valid email address.');
            }
            
            error_log("Sending email to: $to_email");
            
            // Send email
            return $this->sendMessage($to_email, $subject, $message, $template['id'], $booking_id);
            
        } catch (Exception $e) {
            error_log("Email sendBookingEmail error: " . $e->getMessage());
            return [
                'status' => 'error',
                'message' => $e->getMessage()
            ];
        }
    }
    
    private function prepareBookingVariables($booking) {
        return [
            'consignee_name' => $booking['consignee_name'],
            'cn_number' => $booking['cn_number'],
            'consignor_name' => $booking['consignor_name'],
            'content' => $booking['content'] ?? 'N/A',
            'total_amount' => number_format($booking['total_amount'], 2),
            'booking_date' => $booking['booking_date'],
            'tracking_url' => $this->generateTrackingUrl($booking['cn_number']),
            'status' => $booking['status'] == 1 ? 'Active' : 'Inactive',
            'cancellation_reason' => 'N/A', // This would be set when cancelling
            'company_name' => $this->settings['from_name'] ?? 'Booking System'
        ];
    }
    
    private function replaceTemplateVariables($template, $variables) {
        foreach ($variables as $key => $value) {
            $template = str_replace('{' . $key . '}', $value, $template);
        }
        return $template;
    }
    
    private function generateTrackingUrl($cn_number) {
        $base_url = $_SERVER['HTTP_HOST'] ?? 'localhost';
        return "https://$base_url/track.php?cn=$cn_number";
    }
}

// Handle API requests only if this file is called directly
if ($_SERVER['REQUEST_METHOD'] === 'POST' && basename($_SERVER['SCRIPT_NAME']) === 'send_message.php') {
    try {
        $action = $_POST['action'] ?? '';
        
        if ($action === 'resend') {
            // Handle resend functionality
            $log_id = $_POST['log_id'] ?? '';
            if (empty($log_id)) {
                throw new Exception('Log ID is required for resend');
            }
            
            // Get the original message log
            $stmt = $pdo->prepare("SELECT * FROM email_message_logs WHERE id = ?");
            $stmt->execute([$log_id]);
            $log = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$log) {
                throw new Exception('Message log not found');
            }
            
            $email = new EmailSender($pdo);
            $result = $email->sendMessage($log['to_email'], $log['subject'], $log['message_content'], $log['template_id'], $log['booking_id']);
            
            echo json_encode($result);
            
        } else {
            // Handle normal message sending
            $to_email = $_POST['to_email'] ?? '';
            $subject = $_POST['subject'] ?? '';
            $message = $_POST['message'] ?? '';
            $template_id = $_POST['template_id'] ?? null;
            $booking_id = $_POST['booking_id'] ?? null;
            
            if (empty($to_email) || empty($subject) || empty($message)) {
                throw new Exception('Email address, subject, and message are required');
            }
            
            $email = new EmailSender($pdo);
            $result = $email->sendMessage($to_email, $subject, $message, $template_id, $booking_id);
            
            echo json_encode($result);
        }
        
    } catch (Exception $e) {
        echo json_encode([
            'status' => 'error',
            'message' => $e->getMessage()
        ]);
    }
}
?> 