<?php

namespace SSCI\Classes;

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

/**
 * Notification Class
 * Handles multi-channel notifications: Email (PHPMailer), SMS (sms-gate), WhatsApp (ultramsg), Push, and In-App
 * 
 * Features:
 * - Message templates with dynamic placeholders
 * - Bilingual email support (EN/FR)
 * - Rich HTML email templates with modern design
 * - Push notifications paired with in-app notifications
 * - Audit logging of all notifications sent
 * 
 * VAPID Keys (for push notifications):
 * Public: 1zslCAtC2eJWkbu6YjcQkpq38IzzAvaK3FjCArEs2CE
 * Private: MQeQK4d-NKdEz3ULV6zztFZKKkRhrMm62ak0DQjSQI0
 */
class Notification
{
    private $db;
    private $config;
    private $userId;
    private $user;
    private $channels = [];
    private $title = '';
    private $message = '';
    private $template = null;
    private $templateData = [];
    private $type = 'info';
    private $data = [];
    private $language = 'en';
    private $emailTheme = 'modern';
    private $ctaButton = null;
    private $ctaUrl = null;

    private static $staticDb = null;
    private static $staticConfig = null;

    public function __construct($db = null, $config = null, $userId = null)
    {
        $this->db = $db ?? self::$staticDb;
        $this->config = $config ?? self::$staticConfig;
        $this->userId = $userId;
        
        if ($userId && $this->db) {
            $this->loadUser();
        }
    }

    /**
     * Reset notification state - useful when reusing notification object
     */
    public function reset()
    {
        $this->userId = null;
        $this->user = null;
        $this->channels = [];
        $this->title = '';
        $this->message = '';
        $this->template = null;
        $this->templateData = [];
        $this->type = 'info';
        $this->data = [];
        $this->language = 'en';
        $this->emailTheme = 'modern';
        $this->ctaButton = null;
        $this->ctaUrl = null;
        return $this;
    }

    /**
     * Set static database and config for convenience methods
     */
    public static function setStatic($db, $config)
    {
        self::$staticDb = $db;
        self::$staticConfig = $config;
    }

    /**
     * Load user details
     */
    private function loadUser()
    {
        try {
            $this->user = $this->db->fetch("SELECT id, name, email, phone, whatsapp FROM users WHERE id = ?", [$this->userId]);
        } catch (\Exception $e) {
            error_log("Error loading user: " . $e->getMessage());
        }
    }

    /**
     * Set notification title
     */
    public function setTitle($title)
    {
        $this->title = $title;
        return $this;
    }

    /**
     * Set notification message
     */
    public function setMessage($message)
    {
        $this->message = $message;
        return $this;
    }

    /**
     * Use a message template with dynamic placeholders
     * 
     * Templates support {{placeholder}} syntax
     * Example: "Hello {{name}}, your payment of {{amount}} was received."
     */
    public function useTemplate($templateName, $templateData = [])
    {
        $this->template = $templateName;
        $this->templateData = (array) $templateData;
        $this->message = $this->renderTemplate();
        return $this;
    }

    /**
     * Render template with data placeholders
     */
    private function renderTemplate()
    {
        if (!$this->template) {
            return $this->message;
        }

        // Get template from language file
        $templates = $this->getMessageTemplates();
        $template = $templates[$this->template] ?? $this->template;

        // Replace placeholders
        foreach ($this->templateData as $key => $value) {
            $template = str_replace('{{' . $key . '}}', $value, $template);
        }

        return $template;
    }

    /**
     * Get available message templates
     */
    private function getMessageTemplates()
    {
        return [
            'welcome' => $this->language === 'fr' 
                ? 'Bienvenue {{name}}! Votre compte a été créé avec succès.'
                : 'Welcome {{name}}! Your account has been successfully created.',
            
            'payment_received' => $this->language === 'fr'
                ? 'Paiement reçu! {{amount}} a été enregistré pour {{invoice_ref}}.'
                : 'Payment received! {{amount}} has been recorded for {{invoice_ref}}.',
            
            'payment_failed' => $this->language === 'fr'
                ? 'Échec du paiement pour {{invoice_ref}}. Veuillez réessayer.'
                : 'Payment failed for {{invoice_ref}}. Please try again.',
            
            'invoice_created' => $this->language === 'fr'
                ? 'Facture {{invoice_ref}} créée pour {{amount}}. Due: {{due_date}}'
                : 'Invoice {{invoice_ref}} created for {{amount}}. Due: {{due_date}}',
            
            'staff_added' => $this->language === 'fr'
                ? '{{staff_name}} a été ajouté(e) en tant que {{role}}.'
                : '{{staff_name}} has been added as {{role}}.',
            
            'client_updated' => $this->language === 'fr'
                ? 'Profil client {{client_name}} mis à jour.'
                : 'Client profile {{client_name}} has been updated.',
            
            'password_reset' => $this->language === 'fr'
                ? 'Un lien de réinitialisation de mot de passe a été envoyé à {{email}}.'
                : 'A password reset link has been sent to {{email}}.',
            
            'access_granted' => $this->language === 'fr'
                ? 'Accès accordé à {{resource}} jusqu\'au {{expiry_date}}.'
                : 'Access granted to {{resource}} until {{expiry_date}}.',
        ];
    }

    /**
     * Set language for multilingual templates
     */
    public function setLanguage($language)
    {
        $this->language = in_array($language, ['en', 'fr']) ? $language : 'en';
        return $this;
    }

    /**
     * Add a call-to-action button to email
     */
    public function addCallToAction($buttonText, $url, $style = 'primary')
    {
        $this->ctaButton = $buttonText;
        $this->ctaUrl = $url;
        return $this;
    }

    /**
     * Set notification type
     */
    public function setType($type)
    {
        if (in_array($type, ['info', 'success', 'warning', 'error'])) {
            $this->type = $type;
        }
        return $this;
    }

    /**
     * Add custom data
     */
    public function setData($data)
    {
        $this->data = (array) $data;
        return $this;
    }

    /**
     * Set user ID for this notification
     */
    public function forUser($userId)
    {
        $this->userId = $userId;
        if ($this->db) {
            $this->loadUser();
        }
        return $this;
    }

    /**
     * Enable channels for this notification
     */
    public function via($channels)
    {
        $this->channels = (array) $channels;
        return $this;
    }

    /**
     * Send notification via specified channels
     * In-app notifications are always sent
     * Other channels are only sent if enabled in settings
     */
    public function send()
    {
        if (empty($this->channels) || !$this->user) {
            return false;
        }

        // Get channel enablement settings from database
        $settings = $this->db->fetch("SELECT email_notifications_enabled, sms_notifications_enabled, whatsapp_notifications_enabled, push_notifications_enabled FROM settings LIMIT 1");
        
        $results = [];
        $failedChannels = [];

        foreach ($this->channels as $channel) {
            try {
                switch ($channel) {
                    case 'email':
                        // Check if email notifications are enabled
                        if (empty($settings['email_notifications_enabled'])) {
                            $results['email'] = false;
                            $failedChannels['email'] = 'Email notifications disabled in settings';
                            break;
                        }
                        $results['email'] = $this->sendEmail();
                        if (!$results['email']) {
                            $failedChannels['email'] = 'Failed to send email (check SMTP configuration)';
                        }
                        break;
                    case 'sms':
                        // Check if SMS notifications are enabled
                        if (empty($settings['sms_notifications_enabled'])) {
                            $results['sms'] = false;
                            $failedChannels['sms'] = 'SMS notifications disabled in settings';
                            break;
                        }
                        $results['sms'] = $this->sendSMS();
                        if (!$results['sms']) {
                            $failedChannels['sms'] = 'Failed to send SMS (check SMS gateway configuration)';
                        }
                        break;
                    case 'whatsapp':
                        // Check if WhatsApp notifications are enabled
                        if (empty($settings['whatsapp_notifications_enabled'])) {
                            $results['whatsapp'] = false;
                            $failedChannels['whatsapp'] = 'WhatsApp notifications disabled in settings';
                            break;
                        }
                        $results['whatsapp'] = $this->sendWhatsApp();
                        if (!$results['whatsapp']) {
                            $failedChannels['whatsapp'] = 'Failed to send WhatsApp (check WhatsApp API configuration)';
                        }
                        break;
                    case 'push':
                        // Check if push notifications are enabled
                        if (empty($settings['push_notifications_enabled'])) {
                            $results['push'] = false;
                            $failedChannels['push'] = 'Push notifications disabled in settings';
                            break;
                        }
                        $results['push'] = $this->sendPush();
                        if (!$results['push']) {
                            $failedChannels['push'] = 'Failed to send push notification (check VAPID keys)';
                        }
                        break;
                    case 'in-app':
                        // In-app notifications are always sent
                        $results['in-app'] = $this->sendInApp();
                        if (!$results['in-app']) {
                            $failedChannels['in-app'] = 'Failed to store in-app notification';
                        }
                        break;
                }
            } catch (\Exception $e) {
                $results[$channel] = false;
                $failedChannels[$channel] = $e->getMessage();
            }
        }

        // Always ensure in-app notification is sent as fallback
        if (!isset($results['in-app'])) {
            try {
                $results['in-app'] = $this->sendInApp();
                if (!$results['in-app']) {
                    $failedChannels['in-app'] = 'Failed to store in-app notification';
                }
            } catch (\Exception $e) {
                $failedChannels['in-app'] = $e->getMessage();
            }
        }

        // Log any failed channels for debugging
        if (!empty($failedChannels)) {
            error_log("Notification sending partially failed for user {$this->userId}: " . json_encode($failedChannels));
        }

        return $results;
    }

    /**
     * Send in-app notification (also triggers push notification)
     */
    private function sendInApp()
    {
        try {
            $this->db->query(
                "INSERT INTO notifications (user_id, title, message, type, created_at)
                VALUES (?, ?, ?, ?, NOW())",
                [
                    $this->userId,
                    $this->title,
                    $this->message,
                    $this->type
                ]
            );
            
            $result = true;

            // Automatically send push notification whenever in-app notification is sent
            if ($result) {
                $this->sendPush();
                $this->logNotificationSent(['in-app', 'push']);
            }

            return $result;
        } catch (\Exception $e) {
            error_log("In-app notification error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send email notification
     */
    private function sendEmail()
    {
        try {
            if (!$this->user['email']) {
                return false;
            }

            $mail = new PHPMailer(true);

            // Get SMTP settings from database
            $settings = $this->db->fetch("SELECT smtp_host, smtp_port, smtp_user, smtp_password, smtp_from, site_name, email_enabled FROM settings LIMIT 1");
            
            if (!$settings || !$settings['email_enabled'] || !$settings['smtp_host']) {
                return false;
            }

            $mail->isSMTP();
            $mail->Host = $settings['smtp_host'];
            $mail->Port = intval($settings['smtp_port'] ?? 587);
            $mail->SMTPAuth = true;
            $mail->Username = $settings['smtp_user'] ?? '';
            $mail->Password = $settings['smtp_password'] ?? '';
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->setFrom($settings['smtp_from'] ?? 'noreply@ssci.local', $settings['site_name'] ?? 'SSCI Office');
            $mail->addAddress($this->user['email'], $this->user['name']);
            $mail->isHTML(true);
            $mail->Subject = $this->title;
            $mail->Body = $this->getEmailHTML();
            $mail->AltBody = strip_tags($this->message);
            return $mail->send();
        } catch (Exception $e) {
            error_log("Email notification error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Get email HTML template - Modern, Colorful, Bilingual
     */
    private function getEmailHTML()
    {
        $typeStyles = [
            'success' => [
                'color' => '#059669',
                'bgColor' => '#ecfdf5',
                'icon' => '✓',
                'label' => $this->language === 'fr' ? 'Succès' : 'Success'
            ],
            'error' => [
                'color' => '#dc2626',
                'bgColor' => '#fef2f2',
                'icon' => '✕',
                'label' => $this->language === 'fr' ? 'Erreur' : 'Error'
            ],
            'warning' => [
                'color' => '#d97706',
                'bgColor' => '#fffbeb',
                'icon' => '!',
                'label' => $this->language === 'fr' ? 'Avertissement' : 'Warning'
            ],
            'info' => [
                'color' => '#0284c7',
                'bgColor' => '#f0f9ff',
                'icon' => 'ℹ',
                'label' => $this->language === 'fr' ? 'Info' : 'Info'
            ]
        ];

        $style = $typeStyles[$this->type] ?? $typeStyles['info'];
        $message = htmlspecialchars($this->message);
        $title = htmlspecialchars($this->title);
        $footer = $this->language === 'fr' 
            ? 'Ceci est un message automatisé de SSCI Office. Ne répondez pas à cet email.'
            : 'This is an automated message from SSCI Office. Please do not reply to this email.';

        $ctaButton = '';
        if ($this->ctaButton && $this->ctaUrl) {
            $ctaText = htmlspecialchars($this->ctaButton);
            $ctaUrl = htmlspecialchars($this->ctaUrl);
            $ctaButton = "
                <div style='margin: 30px 0; text-align: center;'>
                    <a href='{$ctaUrl}' style='display: inline-block; background-color: {$style['color']}; color: white; padding: 12px 30px; border-radius: 6px; text-decoration: none; font-weight: bold; font-size: 16px; transition: all 0.3s ease;'>
                        {$ctaText}
                    </a>
                </div>
            ";
        }

        return "
<!DOCTYPE html>
<html>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            padding: 0;
        }
        .container {
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }
        .header {
            text-align: center;
            color: white;
            padding: 30px 0;
        }
        .header h1 {
            margin: 0;
            font-size: 28px;
            font-weight: 700;
        }
        .content {
            background-color: white;
            border-radius: 12px;
            padding: 40px;
            box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
        }
        .status-badge {
            display: inline-block;
            background-color: {$style['bgColor']};
            color: {$style['color']};
            padding: 8px 16px;
            border-radius: 20px;
            font-weight: 600;
            font-size: 12px;
            margin-bottom: 20px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        .title {
            color: #1f2937;
            font-size: 24px;
            font-weight: 700;
            margin: 15px 0 10px 0;
            line-height: 1.3;
        }
        .message {
            color: #6b7280;
            font-size: 16px;
            line-height: 1.8;
            margin: 20px 0;
        }
        .divider {
            border: none;
            border-top: 2px solid #e5e7eb;
            margin: 30px 0;
        }
        .metadata {
            background-color: #f9fafb;
            padding: 15px;
            border-radius: 8px;
            margin: 20px 0;
            font-size: 14px;
            color: #6b7280;
        }
        .metadata-item {
            margin: 8px 0;
        }
        .metadata-label {
            font-weight: 600;
            color: #374151;
        }
        .footer {
            text-align: center;
            padding: 20px 0;
            color: #9ca3af;
            font-size: 13px;
            border-top: 1px solid #e5e7eb;
            margin-top: 30px;
        }
        .footer a {
            color: #6b7280;
            text-decoration: none;
        }
        .cta-button {
            display: inline-block;
            background: linear-gradient(135deg, {$style['color']}, {$style['color']});
            color: white;
            padding: 14px 32px;
            border-radius: 8px;
            text-decoration: none;
            font-weight: 600;
            font-size: 16px;
            transition: all 0.3s ease;
            margin: 30px 0;
        }
        .icon {
            font-size: 48px;
            margin-bottom: 10px;
            animation: fadeIn 0.5s ease;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }
    </style>
</head>
<body>
    <div class='container'>
        <div class='header'>
            <h1>📬 SSCI Office</h1>
        </div>
        
        <div class='content'>
            <div class='icon' style='text-align: center;'>{$style['icon']}</div>
            <div class='status-badge'>{$style['label']}</div>
            
            <h2 class='title'>{$title}</h2>
            <p class='message'>{$message}</p>
            
            {$ctaButton}
            
            " . ($this->data ? "
            <div class='metadata'>
                " . $this->formatMetadata() . "
            </div>
            " : "") . "
            
            <div class='footer'>
                {$footer}
                <br><br>
                <a href='#'>&copy; 2024 SSCI Office Platform</a>
            </div>
        </div>
    </div>
</body>
</html>
        ";
    }

    /**
     * Format metadata for display in email
     */
    private function formatMetadata()
    {
        $html = '';
        foreach ($this->data as $key => $value) {
            if (is_array($value) || is_object($value)) {
                $value = json_encode($value);
            }
            $key = ucfirst(str_replace('_', ' ', $key));
            $value = htmlspecialchars($value);
            $html .= "<div class='metadata-item'><span class='metadata-label'>$key:</span> $value</div>";
        }
        return $html;
    }

    /**
     * Send SMS notification
     */
    private function sendSMS()
    {
        try {
            if (!$this->user['phone']) {
                error_log("SMS skipped: User has no phone number");
                return false;
            }

            // Get SMS settings from database
            $settings = $this->db->fetch("SELECT sms_username, sms_password, sms_notifications_enabled FROM settings LIMIT 1");
            
            if (!$settings) {
                error_log("SMS skipped: No settings found");
                return false;
            }

            if (!$settings['sms_notifications_enabled']) {
                error_log("SMS skipped: SMS notifications not enabled in settings");
                return false;
            }

            if (!$settings['sms_username'] || !$settings['sms_password']) {
                error_log("SMS skipped: SMS username or password not configured");
                return false;
            }

            // Format phone number
            $phone = $this->formatPhoneNumber($this->user['phone']);
            $phoneNumbers = [$phone];

            error_log("SMS: Sending to $phone");

            // Create request body
            $body = json_encode([
                "textMessage" => [
                    "text" => substr($this->message, 0, 160)
                ],
                "phoneNumbers" => $phoneNumbers
            ]);

            // Send via sms-gate using basic auth (username:password)
            $credentials = $settings['sms_username'] . ':' . $settings['sms_password'];
            $curl = curl_init();
            curl_setopt_array($curl, [
                CURLOPT_URL => "https://api.sms-gate.app/3rdparty/v1/message",
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_USERPWD => $credentials,
                CURLOPT_POSTFIELDS => $body,
                CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
                CURLOPT_SSL_VERIFYPEER => 0,
                CURLOPT_SSL_VERIFYHOST => 0,
            ]);

            $response = curl_exec($curl);
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            $error = curl_error($curl);
            curl_close($curl);

            if ($error) {
                error_log("SMS curl error: $error");
                return false;
            }

            error_log("SMS response ($httpCode): $response");
            $result = json_decode($response, true);
            // SMS-gate API returns HTTP 202 with id and state: "Pending" or "Sent"
            $success = ($httpCode == 202 && isset($result['id'])) || 
                      (isset($result['status']) && ($result['status'] === 'ok' || $result['status'] === 'success'));
            error_log("SMS result: " . ($success ? "Success" : "Failed"));
            return $success;
        } catch (\Exception $e) {
            error_log("SMS notification error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send WhatsApp notification
     */
    private function sendWhatsApp()
    {
        try {
            if (!$this->user['whatsapp']) {
                error_log("WhatsApp skipped: User has no WhatsApp number");
                return false;
            }

            // Get WhatsApp settings from database
            $settings = $this->db->fetch("SELECT whatsapp_api_token, whatsapp_instance_id, whatsapp_notifications_enabled FROM settings LIMIT 1");
            
            if (!$settings) {
                error_log("WhatsApp skipped: No settings found");
                return false;
            }

            if (!$settings['whatsapp_notifications_enabled']) {
                error_log("WhatsApp skipped: WhatsApp notifications not enabled in settings");
                return false;
            }

            if (!$settings['whatsapp_api_token'] || !$settings['whatsapp_instance_id']) {
                error_log("WhatsApp skipped: Missing WhatsApp API token or instance ID");
                return false;
            }

            $apiToken = $settings['whatsapp_api_token'];
            $instanceId = $settings['whatsapp_instance_id'];

            // Format WhatsApp number
            $whatsappNumber = $this->formatPhoneNumber($this->user['whatsapp']);

            error_log("WhatsApp: Sending to $whatsappNumber with instance $instanceId");

            // Prepare request
            $params = [
                'token' => $apiToken,
                'to' => $whatsappNumber,
                'body' => $this->title . "\n\n" . $this->message
            ];

            $url = "https://api.ultramsg.com/instance{$instanceId}/messages/chat";
            error_log("WhatsApp URL: $url");

            $curl = curl_init();
            curl_setopt_array($curl, [
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => "",
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_SSL_VERIFYHOST => 0,
                CURLOPT_SSL_VERIFYPEER => 0,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_POSTFIELDS => http_build_query($params),
                CURLOPT_HTTPHEADER => ["content-type: application/x-www-form-urlencoded"],
            ]);

            $response = curl_exec($curl);
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            $error = curl_error($curl);
            curl_close($curl);

            if ($error) {
                error_log("WhatsApp curl error: $error");
                return false;
            }

            error_log("WhatsApp response ($httpCode): $response");
            $result = json_decode($response, true);
            // UltraMsg API returns "sent":"true" or checks for success field differently
            $success = (isset($result['sent']) && $result['sent'] === 'true') || 
                      (isset($result['sent']) && $result['sent'] === true) ||
                      (isset($result['success']) && $result['success'] === true);
            error_log("WhatsApp result: " . ($success ? "Success" : "Failed"));
            return $success;
        } catch (\Exception $e) {
            error_log("WhatsApp notification error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send push notification
     */
    private function sendPush()
    {
        try {
            // Get user's push subscriptions
            if (!$this->userId || !$this->db) {
                return false;
            }

            $subscriptions = $this->db->fetchAll(
                "SELECT id, endpoint, p256dh, auth FROM user_push_subscriptions WHERE user_id = ?",
                [$this->userId]
            );

            if (empty($subscriptions)) {
                error_log("Push: No subscriptions found for user {$this->userId}");
                return false;
            }

            // Get VAPID keys from settings
            $settings = $this->db->fetch("SELECT vapid_public_key, vapid_private_key FROM settings LIMIT 1");
            if (empty($settings['vapid_public_key']) || empty($settings['vapid_private_key'])) {
                error_log("Push: VAPID keys not configured in settings");
                return false;
            }

            // Prepare push notification payload
            $payload = json_encode([
                'title' => $this->title,
                'body' => $this->message,
                'icon' => '/images/logo.png',
                'badge' => '/images/badge.png',
                'tag' => 'notification-' . time(),
                'data' => [
                    'type' => $this->type,
                    'data' => $this->data,
                    'url' => '/?page=dashboard'
                ]
            ]);

            $successCount = 0;
            $failedCount = 0;

            // Send to each subscription
            foreach ($subscriptions as $subscription) {
                try {
                    $result = $this->sendWebPush(
                        $subscription['endpoint'],
                        $payload,
                        $subscription['p256dh'],
                        $subscription['auth'],
                        $settings['vapid_public_key'],
                        $settings['vapid_private_key']
                    );

                    if ($result) {
                        $successCount++;
                    } else {
                        $failedCount++;
                        // Delete invalid subscription
                        $this->db->query("DELETE FROM user_push_subscriptions WHERE id = ?", [$subscription['id']]);
                    }
                } catch (\Exception $e) {
                    error_log("Push notification error for subscription {$subscription['id']}: " . $e->getMessage());
                    $failedCount++;
                }
            }

            error_log("Push notifications sent: {$successCount} succeeded, {$failedCount} failed for user {$this->userId}");
            return $successCount > 0;

        } catch (\Exception $e) {
            error_log("Push notification error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Send Web Push notification using VAPID
     */
    private function sendWebPush($endpoint, $payload, $p256dh, $auth, $vapidPublic, $vapidPrivate)
    {
        try {
            // Encode payload
            $payloadEncoded = $payload;

            // Prepare headers
            $headers = [
                'Content-Type: application/octet-stream',
                'Content-Length: ' . strlen($payloadEncoded),
                'TTL: 24'
            ];

            // Add VAPID authentication header
            $authHeader = $this->generateVAPIDAuthHeader($vapidPublic, $vapidPrivate, $endpoint);
            if ($authHeader) {
                $headers[] = $authHeader;
            }

            // Send push notification via cURL
            $ch = curl_init($endpoint);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadEncoded);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            // 201 Created or 200 OK means success
            return in_array($httpCode, [200, 201]);

        } catch (\Exception $e) {
            error_log("Web push error: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Generate VAPID Authentication header for web push
     */
    private function generateVAPIDAuthHeader($vapidPublic, $vapidPrivate, $endpoint)
    {
        try {
            // Simple JWT generation for VAPID
            // Note: This is a simplified implementation. Production should use a proper library
            
            $header = base64_encode(json_encode(['typ' => 'JWT', 'alg' => 'HS256']));
            $time = time();
            $claim = base64_encode(json_encode([
                'aud' => parse_url($endpoint, PHP_URL_SCHEME) . '://' . parse_url($endpoint, PHP_URL_HOST),
                'exp' => $time + 3600,
                'sub' => 'mailto:' . config('app.email', 'info@ssci.cm')
            ]));

            // Create signature (simplified - proper VAPID needs proper crypto)
            $signature = base64_encode(hash_hmac('sha256', "$header.$claim", $vapidPrivate, true));
            
            $jwt = "$header.$claim.$signature";

            return "Authorization: vapid t=$jwt, k=$vapidPublic";

        } catch (\Exception $e) {
            error_log("VAPID header generation error: " . $e->getMessage());
            return null;
        }
    }

    /**
     * Format phone number to international standard
     */
    private function formatPhoneNumber($phone)
    {
        // Remove all non-numeric characters
        $phone = preg_replace('/[^0-9+]/', '', $phone);

        // If doesn't start with +, assume Cameroon country code
        if (strpos($phone, '+') !== 0) {
            if (strpos($phone, '237') === 0) {
                $phone = '+' . $phone;
            } else if (strpos($phone, '0') === 0) {
                $phone = '+237' . substr($phone, 1);
            } else {
                $phone = '+237' . $phone;
            }
        }

        return $phone;
    }

    /**
     * Log notification sent via audit trail
     */
    private function logNotificationSent($channels)
    {
        try {
            // Only log if AuditLog class exists
            if (!class_exists('AuditLog')) {
                return;
            }

            $log = new AuditLog($this->db);
            $log->log(
                AuditLog::ACTION_SEND_NOTIFICATION,
                'notifications',
                null,
                $this->title,
                $this->userId,
                [
                    'channels' => $channels,
                    'type' => $this->type,
                    'recipients' => $this->user['email'] ?? null
                ]
            );
        } catch (\Exception $e) {
            error_log("Audit log notification error: " . $e->getMessage());
        }
    }

    /**
     * Convenience method: Notify user on Create action
     */
    public static function notifyCreate($userId, $itemType, $itemName, $language = 'en')
    {
        $notification = new self(null, null, $userId);
        $notification
            ->setLanguage($language)
            ->setTitle($language === 'fr' ? "Nouveau $itemType créé" : "New $itemType Created")
            ->setMessage("$itemName has been successfully created.")
            ->setType('success')
            ->setData(['action' => 'create', 'type' => $itemType, 'name' => $itemName])
            ->via(['in-app', 'email'])
            ->send();
    }

    /**
     * Convenience method: Notify user on Update action
     */
    public static function notifyUpdate($userId, $itemType, $itemName, $language = 'en')
    {
        $notification = new self(null, null, $userId);
        $notification
            ->setLanguage($language)
            ->setTitle($language === 'fr' ? "$itemType mise à jour" : "$itemType Updated")
            ->setMessage("$itemName has been successfully updated.")
            ->setType('info')
            ->setData(['action' => 'update', 'type' => $itemType, 'name' => $itemName])
            ->via(['in-app', 'email'])
            ->send();
    }

    /**
     * Convenience method: Notify user on Delete action
     */
    public static function notifyDelete($userId, $itemType, $itemName, $language = 'en')
    {
        $notification = new self(null, null, $userId);
        $notification
            ->setLanguage($language)
            ->setTitle($language === 'fr' ? "$itemType supprimé" : "$itemType Deleted")
            ->setMessage("$itemName has been successfully deleted.")
            ->setType('warning')
            ->setData(['action' => 'delete', 'type' => $itemType, 'name' => $itemName])
            ->via(['in-app', 'email'])
            ->send();
    }

    /**
     * Convenience method: Send templated notification
     */
    public static function notifyTemplate($userId, $templateName, $templateData = [], $language = 'en', $channels = ['in-app', 'email'])
    {
        $notification = new self(null, null, $userId);
        $notification
            ->setLanguage($language)
            ->setTitle($templateName)
            ->useTemplate($templateName, $templateData)
            ->setType('info')
            ->setData(['template' => $templateName])
            ->via($channels)
            ->send();
    }

    /**
     * Create in-app notification (legacy method)
     */
    public function createInAppNotification(int $userId, string $title, string $message, string $type = 'info', ?string $link = null): bool
    {
        try {
            return $this->db->query(
                "INSERT INTO notifications (user_id, title, message, type, data, created_at) VALUES (?, ?, ?, ?, ?, NOW())",
                [
                $userId,
                $title,
                $message,
                $type,
                json_encode(['link' => $link])
            ]);
        } catch (\Exception $e) {
            error_log("Error creating in-app notification: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Get user notifications
     */
    public function getUserNotifications(int $userId, int $limit = 20, bool $unreadOnly = false): array
    {
        try {
            $sql = "SELECT * FROM notifications WHERE user_id = ?";
            $params = [$userId];

            if ($unreadOnly) {
                $sql .= " AND read_at IS NULL";
            }

            $sql .= " ORDER BY created_at DESC LIMIT " . (int)$limit;

            return $this->db->fetchAll($sql, $params);
        } catch (\Exception $e) {
            error_log("Error getting notifications: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Mark notification as read
     */
    public function markAsRead(int $notificationId): bool
    {
        try {
            $this->db->query("UPDATE notifications SET read_at = NOW() WHERE id = ?", [$notificationId]);
            return true;
        } catch (\Exception $e) {
            error_log("Error marking notification as read: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Mark all user notifications as read
     */
    public function markAllAsRead(int $userId): bool
    {
        try {
            $this->db->query("UPDATE notifications SET read_at = NOW() WHERE user_id = ? AND read_at IS NULL", [$userId]);
            return true;
        } catch (\Exception $e) {
            error_log("Error marking all notifications as read: " . $e->getMessage());
            return false;
        }
    }
}
