<?php
/**
 * EasyStream Email Queue System
 * SendGrid/AWS SES integration with queue processing
 * Version: 1.0
 */

defined('_ISVALID') or header('Location: /error');

class VEmailQueue {
    private static $db;
    private static $sendgrid_api_key = null;
    private static $from_email = 'noreply@easystream.com';
    private static $from_name = 'EasyStream';

    public static function init() {
        self::$db = VDatabase::getInstance();

        // Load configuration
        $config = VGenerate::getConfig('email_config');
        if ($config) {
            self::$sendgrid_api_key = $config['sendgrid_api_key'] ?? null;
            self::$from_email = $config['from_email'] ?? self::$from_email;
            self::$from_name = $config['from_name'] ?? self::$from_name;
        }
    }

    /**
     * Queue email for sending
     * @param int $usr_id User ID (optional)
     * @param string $to_email Recipient email
     * @param string $subject Email subject
     * @param string $body_html HTML body
     * @param array $options Additional options
     * @return int Email ID
     */
    public static function queueEmail($usr_id, $to_email, $subject, $body_html, $options = []) {
        self::init();

        $usr_id_val = $usr_id ? (int)$usr_id : 'NULL';
        $to_email_safe = VDatabase::escape($to_email);
        $to_name_safe = VDatabase::escape($options['to_name'] ?? '');
        $subject_safe = VDatabase::escape($subject);
        $body_html_safe = VDatabase::escape($body_html);
        $body_text_safe = VDatabase::escape($options['body_text'] ?? strip_tags($body_html));
        $template_safe = VDatabase::escape($options['template_name'] ?? '');
        $template_data = VDatabase::escape(json_encode($options['template_data'] ?? []));
        $priority = (int)($options['priority'] ?? 5);
        $send_at = isset($options['send_at']) ? "'" . VDatabase::escape($options['send_at']) . "'" : 'NULL';

        $sql = "INSERT INTO db_email_queue
                (usr_id, to_email, to_name, subject, body_html, body_text, template_name, template_data, priority, send_at, status, created_at)
                VALUES ($usr_id_val, '$to_email_safe', '$to_name_safe', '$subject_safe', '$body_html_safe', '$body_text_safe', '$template_safe', '$template_data', $priority, $send_at, 'pending', NOW())";

        if (self::$db->execute($sql)) {
            return self::$db->insert_id();
        }

        return false;
    }

    /**
     * Process email queue
     * @param int $limit Number of emails to process
     * @return array Results
     */
    public static function processQueue($limit = 50) {
        self::init();

        $limit = (int)$limit;

        // Get pending emails
        $sql = "SELECT * FROM db_email_queue
                WHERE status = 'pending'
                AND (send_at IS NULL OR send_at <= NOW())
                ORDER BY priority ASC, created_at ASC
                LIMIT $limit";

        $result = self::$db->execute($sql);

        if (!$result) {
            return ['sent' => 0, 'failed' => 0];
        }

        $sent = 0;
        $failed = 0;

        while ($row = $result->FetchRow()) {
            $email_id = (int)$row['email_id'];

            // Mark as sending
            self::$db->execute("UPDATE db_email_queue SET status = 'sending' WHERE email_id = $email_id");

            // Send email
            $success = self::sendEmail($row);

            if ($success) {
                self::$db->execute("UPDATE db_email_queue SET status = 'sent', sent_at = NOW() WHERE email_id = $email_id");
                self::logEmail($email_id, $row, 'sent');
                $sent++;
            } else {
                $attempts = (int)$row['attempts'] + 1;
                $max_attempts = 3;

                if ($attempts >= $max_attempts) {
                    self::$db->execute("UPDATE db_email_queue SET status = 'failed', attempts = $attempts WHERE email_id = $email_id");
                    self::logEmail($email_id, $row, 'failed');
                    $failed++;
                } else {
                    // Retry later
                    self::$db->execute("UPDATE db_email_queue SET status = 'pending', attempts = $attempts WHERE email_id = $email_id");
                }
            }
        }

        return ['sent' => $sent, 'failed' => $failed];
    }

    /**
     * Send individual email
     * @param array $email_data Email data
     * @return bool Success
     */
    private static function sendEmail($email_data) {
        if (self::$sendgrid_api_key) {
            return self::sendViaSendGrid($email_data);
        } else {
            return self::sendViaPHPMailer($email_data);
        }
    }

    /**
     * Send via SendGrid
     */
    private static function sendViaSendGrid($email_data) {
        $url = 'https://api.sendgrid.com/v3/mail/send';

        $data = [
            'personalizations' => [[
                'to' => [['email' => $email_data['to_email'], 'name' => $email_data['to_name']]]
            ]],
            'from' => ['email' => self::$from_email, 'name' => self::$from_name],
            'subject' => $email_data['subject'],
            'content' => [
                ['type' => 'text/html', 'value' => $email_data['body_html']],
                ['type' => 'text/plain', 'value' => $email_data['body_text']]
            ]
        ];

        $json = json_encode($data);

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . self::$sendgrid_api_key,
            'Content-Type: application/json'
        ]);

        $result = curl_exec($ch);
        $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $status_code == 202 || $status_code == 200;
    }

    /**
     * Send via PHP mail (fallback)
     */
    private static function sendViaPHPMailer($email_data) {
        $to = $email_data['to_email'];
        $subject = $email_data['subject'];
        $message = $email_data['body_html'];

        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "Content-type: text/html; charset=UTF-8\r\n";
        $headers .= "From: " . self::$from_name . " <" . self::$from_email . ">\r\n";

        return mail($to, $subject, $message, $headers);
    }

    /**
     * Log email event
     */
    private static function logEmail($email_id, $email_data, $status) {
        $usr_id = $email_data['usr_id'] ?? 'NULL';
        $to_email = VDatabase::escape($email_data['to_email']);
        $subject = VDatabase::escape($email_data['subject']);
        $status_safe = VDatabase::escape($status);

        $sql = "INSERT INTO db_email_logs
                (email_id, usr_id, to_email, subject, status, created_at)
                VALUES ($email_id, $usr_id, '$to_email', '$subject', '$status_safe', NOW())";

        self::$db->execute($sql);
    }

    /**
     * Get user email preferences
     * @param int $usr_id User ID
     * @return array Preferences
     */
    public static function getPreferences($usr_id) {
        self::init();

        $usr_id = (int)$usr_id;

        $sql = "SELECT * FROM db_email_preferences WHERE usr_id = $usr_id";
        $result = self::$db->execute($sql);

        if ($result && $result->RecordCount() > 0) {
            return $result->FetchRow();
        }

        // Return defaults
        return [
            'digest_frequency' => 'weekly',
            'notify_comments' => 1,
            'notify_replies' => 1,
            'notify_likes' => 1,
            'notify_subscribers' => 1,
            'notify_uploads' => 1,
            'notify_live_streams' => 1,
            'notify_mentions' => 1,
            'notify_milestones' => 1,
            'marketing_emails' => 1
        ];
    }

    /**
     * Update email preferences
     * @param int $usr_id User ID
     * @param array $preferences Preferences
     * @return bool Success
     */
    public static function updatePreferences($usr_id, $preferences) {
        self::init();

        $usr_id = (int)$usr_id;

        // Build SET clause
        $sets = [];
        foreach ($preferences as $key => $value) {
            $key_safe = VDatabase::escape($key);
            $value_safe = VDatabase::escape($value);
            $sets[] = "$key_safe = '$value_safe'";
        }
        $setClause = implode(', ', $sets);

        $sql = "INSERT INTO db_email_preferences (usr_id, $setClause, updated_at)
                VALUES ($usr_id, NOW())
                ON DUPLICATE KEY UPDATE $setClause, updated_at = NOW()";

        return self::$db->execute($sql);
    }

    /**
     * Send templated email
     * @param string $template_name Template name
     * @param int $usr_id User ID
     * @param string $to_email Email address
     * @param array $variables Template variables
     * @return int Email ID
     */
    public static function sendTemplate($template_name, $usr_id, $to_email, $variables = []) {
        self::init();

        // Get template
        $template_safe = VDatabase::escape($template_name);
        $sql = "SELECT * FROM db_email_templates WHERE name = '$template_safe' AND is_active = 1";
        $result = self::$db->execute($sql);

        if (!$result || $result->RecordCount() == 0) {
            return false;
        }

        $template = $result->FetchRow();

        // Replace variables
        $subject = $template['subject'];
        $body_html = $template['body_html'];
        $body_text = $template['body_text'];

        foreach ($variables as $key => $value) {
            $subject = str_replace('{' . $key . '}', $value, $subject);
            $body_html = str_replace('{' . $key . '}', $value, $body_html);
            $body_text = str_replace('{' . $key . '}', $value, $body_text);
        }

        return self::queueEmail($usr_id, $to_email, $subject, $body_html, [
            'body_text' => $body_text,
            'template_name' => $template_name,
            'template_data' => $variables
        ]);
    }
}
