const express = require('express');
const router = express.Router();
const { supabaseAdmin } = require('../config/supabase');
const { authenticateUser } = require('../middleware/auth');
const webPush = require('web-push');

// Configure web-push
if (process.env.VAPID_PUBLIC_KEY && process.env.VAPID_PRIVATE_KEY) {
    webPush.setVapidDetails(
        process.env.VAPID_SUBJECT || 'mailto:admin@badecanteen.com',
        process.env.VAPID_PUBLIC_KEY,
        process.env.VAPID_PRIVATE_KEY
    );
}

// Get VAPID public key
router.get('/vapid-public-key', (req, res) => {
    res.json({
        success: true,
        publicKey: process.env.VAPID_PUBLIC_KEY || ''
    });
});

// Subscribe to push notifications
router.post('/subscribe', authenticateUser, async (req, res) => {
    try {
        const { subscription } = req.body;
        const userId = req.user.id;

        if (!subscription || !subscription.endpoint || !subscription.keys) {
            console.error('Invalid subscription object:', subscription);
            return res.status(400).json({ error: 'Invalid subscription data' });
        }

        const p256dh = subscription.keys.p256dh;
        const auth = subscription.keys.auth;

        if (!p256dh || !auth) {
            return res.status(400).json({ error: 'Missing p256dh or auth keys' });
        }

        // Save subscription to database
        const { data, error } = await supabaseAdmin
            .from('push_subscriptions')
            .upsert({
                user_id: userId,
                endpoint: subscription.endpoint,
                p256dh: p256dh,
                auth: auth
            }, { onConflict: 'user_id, endpoint' }) // Match composite unique constraint
            .select()
            .single();

        if (error) throw error;

        res.json({ success: true, subscription: data });
    } catch (error) {
        console.error('Subscribe error:', error);
        res.status(500).json({ error: 'Failed to subscribe to notifications' });
    }
});

// Unsubscribe from push notifications
router.post('/unsubscribe', authenticateUser, async (req, res) => {
    try {
        const { endpoint } = req.body;
        const userId = req.user.id;

        const { error } = await supabaseAdmin
            .from('push_subscriptions')
            .delete()
            .eq('user_id', userId)
            .eq('endpoint', endpoint);

        if (error) throw error;

        res.json({ success: true });
    } catch (error) {
        console.error('Unsubscribe error:', error);
        res.status(500).json({ error: 'Failed to unsubscribe from notifications' });
    }
});

// Get user notifications
router.get('/', authenticateUser, async (req, res) => {
    try {
        const userId = req.user.id;
        const { unread_only } = req.query;

        let query = supabaseAdmin
            .from('notifications')
            .select('*')
            .eq('user_id', userId);

        if (unread_only === 'true') {
            query = query.eq('read_status', false);
        }

        query = query.order('created_at', { ascending: false }).limit(50);

        const { data, error } = await query;

        if (error) throw error;

        res.json({ success: true, notifications: data });
    } catch (error) {
        console.error('Get notifications error:', error);
        res.status(500).json({ error: 'Failed to fetch notifications' });
    }
});

// Mark notification as read
router.patch('/:id/read', authenticateUser, async (req, res) => {
    try {
        const userId = req.user.id;
        const notificationId = req.params.id;

        const { data, error } = await supabaseAdmin
            .from('notifications')
            .update({ read_status: true })
            .eq('id', notificationId)
            .eq('user_id', userId)
            .select()
            .single();

        if (error) throw error;

        res.json({ success: true, notification: data });
    } catch (error) {
        console.error('Mark read error:', error);
        res.status(500).json({ error: 'Failed to mark notification as read' });
    }
});

// Mark all notifications as read
router.post('/mark-all-read', authenticateUser, async (req, res) => {
    try {
        const userId = req.user.id;

        const { error } = await supabaseAdmin
            .from('notifications')
            .update({ read_status: true })
            .eq('user_id', userId)
            .eq('read_status', false);

        if (error) throw error;

        res.json({ success: true });
    } catch (error) {
        console.error('Mark all read error:', error);
        res.status(500).json({ error: 'Failed to mark all notifications as read' });
    }
});

// Send push notification (internal use)
async function sendPushNotification(userId, title, body, data = {}) {
    try {
        // Get user's push subscriptions
        const { data: subscriptions } = await supabaseAdmin
            .from('push_subscriptions')
            .select('*')
            .eq('user_id', userId);

        if (!subscriptions || subscriptions.length === 0) {
            console.log('No push subscriptions found for user:', userId);
            return;
        }

        const payload = JSON.stringify({
            title,
            body,
            icon: '/images/icons/icon-192x192.png',
            badge: '/images/icons/icon-192x192.png',
            data
        });

        // Send to all user's subscriptions
        const promises = subscriptions.map(async (sub) => {
            try {
                await webPush.sendNotification(
                    {
                        endpoint: sub.endpoint,
                        keys: {
                            p256dh: sub.p256dh,
                            auth: sub.auth
                        }
                    },
                    payload
                );
            } catch (error) {
                console.error('Push notification error:', error);
                // If subscription is invalid, remove it
                if (error.statusCode === 410) {
                    await supabaseAdmin
                        .from('push_subscriptions')
                        .delete()
                        .eq('id', sub.id);
                }
            }
        });

        await Promise.all(promises);
    } catch (error) {
        console.error('Send push notification error:', error);
    }
}

// Test notification endpoint (for development)
router.post('/test', authenticateUser, async (req, res) => {
    try {
        const userId = req.user.id;

        await sendPushNotification(
            userId,
            'Test Notification',
            'This is a test notification from Bade Canteen',
            { test: true }
        );

        res.json({ success: true, message: 'Test notification sent' });
    } catch (error) {
        console.error('Test notification error:', error);
        res.status(500).json({ error: 'Failed to send test notification' });
    }
});

module.exports = router;
module.exports.sendPushNotification = sendPushNotification;
