<?php
/**
 * Tom's Java Jive - Push Notification Service
 * 
 * Handles web push notifications using VAPID
 */

class PushNotification {
    private string $publicKey;
    private string $privateKey;
    private string $subject;
    
    public function __construct() {
        // VAPID keys - generate your own at: https://web-push-codelab.glitch.me/
        $this->publicKey = getSetting('vapid_public_key', 'YOUR_VAPID_PUBLIC_KEY');
        $this->privateKey = getSetting('vapid_private_key', 'YOUR_VAPID_PRIVATE_KEY');
        $this->subject = 'mailto:' . getSetting('admin_email', 'admin@tomsjavajive.com');
    }
    
    /**
     * Get VAPID public key for client
     */
    public function getPublicKey(): string {
        return $this->publicKey;
    }
    
    /**
     * Send push notification to a subscription
     */
    public function send(array $subscription, string $title, string $body, array $options = []): array {
        $payload = json_encode([
            'title' => $title,
            'body' => $body,
            'icon' => $options['icon'] ?? '/assets/icons/icon-192.png',
            'badge' => $options['badge'] ?? '/assets/icons/badge-72.png',
            'url' => $options['url'] ?? '/',
            'tag' => $options['tag'] ?? null,
            'data' => $options['data'] ?? []
        ]);
        
        // For now, we'll store notifications for when the user comes online
        // Full web push requires a library like minishlink/web-push
        // This is a simplified version that works with the service worker
        
        try {
            // Store notification for retrieval
            $notificationId = generateId('notif_');
            db()->insert('push_notifications', [
                'notification_id' => $notificationId,
                'subscription_endpoint' => $subscription['endpoint'],
                'payload' => $payload,
                'status' => 'pending',
                'created_at' => date('Y-m-d H:i:s')
            ]);
            
            return ['success' => true, 'notification_id' => $notificationId];
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * Send notification to all subscribed users
     */
    public function broadcast(string $title, string $body, array $options = []): array {
        $subscriptions = db()->fetchAll("SELECT * FROM push_subscriptions WHERE is_active = 1");
        
        $results = ['sent' => 0, 'failed' => 0];
        
        foreach ($subscriptions as $sub) {
            $subscription = [
                'endpoint' => $sub['endpoint'],
                'keys' => [
                    'p256dh' => $sub['p256dh_key'],
                    'auth' => $sub['auth_key']
                ]
            ];
            
            $result = $this->send($subscription, $title, $body, $options);
            
            if ($result['success']) {
                $results['sent']++;
            } else {
                $results['failed']++;
            }
        }
        
        return $results;
    }
    
    /**
     * Send order status update notification
     */
    public function sendOrderUpdate(string $customerId, array $order, string $status): array {
        $subscription = $this->getCustomerSubscription($customerId);
        
        if (!$subscription) {
            return ['success' => false, 'error' => 'No subscription found'];
        }
        
        $messages = [
            'confirmed' => "Your order #{$order['order_number']} has been confirmed!",
            'processing' => "We're preparing your order #{$order['order_number']}",
            'shipped' => "Your order #{$order['order_number']} is on its way!",
            'delivered' => "Your order #{$order['order_number']} has been delivered!",
            'ready' => "Your order #{$order['order_number']} is ready for pickup!"
        ];
        
        return $this->send(
            $subscription,
            "Order Update",
            $messages[$status] ?? "Order #{$order['order_number']} status: {$status}",
            [
                'url' => "/account/order.php?id={$order['order_id']}",
                'tag' => "order-{$order['order_id']}"
            ]
        );
    }
    
    /**
     * Send promotional notification
     */
    public function sendPromotion(string $customerId, string $title, string $message, string $url = '/shop.php'): array {
        $subscription = $this->getCustomerSubscription($customerId);
        
        if (!$subscription) {
            return ['success' => false, 'error' => 'No subscription found'];
        }
        
        return $this->send($subscription, $title, $message, ['url' => $url]);
    }
    
    /**
     * Send loyalty tier notification
     */
    public function sendTierNotification(string $customerId, string $tierName, array $benefits): array {
        $subscription = $this->getCustomerSubscription($customerId);
        
        if (!$subscription) {
            return ['success' => false, 'error' => 'No subscription found'];
        }
        
        return $this->send(
            $subscription,
            "Congratulations! You're now {$tierName}!",
            "Enjoy new benefits: " . implode(', ', array_slice($benefits, 0, 2)),
            ['url' => '/account/']
        );
    }
    
    /**
     * Get customer's push subscription
     */
    private function getCustomerSubscription(string $customerId): ?array {
        $sub = db()->fetch(
            "SELECT * FROM push_subscriptions WHERE customer_id = :id AND is_active = 1 ORDER BY created_at DESC LIMIT 1",
            ['id' => $customerId]
        );
        
        if (!$sub) {
            return null;
        }
        
        return [
            'endpoint' => $sub['endpoint'],
            'keys' => [
                'p256dh' => $sub['p256dh_key'],
                'auth' => $sub['auth_key']
            ]
        ];
    }
}

// Helper function for easy access
function pushNotify(): PushNotification {
    static $instance = null;
    if ($instance === null) {
        $instance = new PushNotification();
    }
    return $instance;
}
