require('dotenv').config();
const express = require('express');
const path = require('path');
const cors = require('cors');
const admin = require('firebase-admin');

const app = express();
const PORT = process.env.PORT || 3000;

// Middleware
app.use(cors());
app.use(express.json());
app.use(express.static('public'));

// In-memory storage for FCM tokens (in production, use a database)
const userTokens = new Map();

// Load tokens from file on startup (for persistence)
const fs = require('fs');
const TOKENS_FILE = './data/tokens.json';

function loadTokens() {
  try {
    if (fs.existsSync(TOKENS_FILE)) {
      const data = fs.readFileSync(TOKENS_FILE, 'utf8');
      const tokens = JSON.parse(data);
      for (const [user, tokenArray] of Object.entries(tokens)) {
        userTokens.set(user, new Set(tokenArray));
      }
      console.log(`Loaded tokens for ${userTokens.size} users from file`);
    }
  } catch (error) {
    console.log('No existing tokens file found, starting fresh');
  }
}

function saveTokens() {
  const tokens = {};
  for (const [user, tokenSet] of userTokens.entries()) {
    tokens[user] = Array.from(tokenSet);
  }
  fs.writeFileSync(TOKENS_FILE, JSON.stringify(tokens, null, 2));
}

// Load existing tokens on startup
loadTokens();

// Auto-save tokens every 30 seconds
setInterval(() => {
  try {
    saveTokens();
  } catch (error) {
    console.error('Auto-save tokens failed:', error);
  }
}, 30000);

// Initialize Firebase Admin
if (process.env.FIREBASE_PRIVATE_KEY) {
  const serviceAccount = {
    projectId: process.env.FIREBASE_PROJECT_ID,
    privateKeyId: process.env.FIREBASE_PRIVATE_KEY_ID,
    privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
    clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
    clientId: process.env.FIREBASE_CLIENT_ID,
    authUri: process.env.FIREBASE_AUTH_URI,
    tokenUri: process.env.FIREBASE_TOKEN_URI,
    authProviderX509CertUrl: process.env.FIREBASE_AUTH_PROVIDER_X509_CERT_URL,
    clientC509CertUrl: process.env.FIREBASE_CLIENT_X509_CERT_URL
  };

  admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
  });
  
  console.log('Firebase Admin initialized successfully');
} else {
  console.log('Firebase Admin not configured. Please set up .env file');
}

// Routes
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// Register FCM token
app.post('/register-token', (req, res) => {
  const { username, token } = req.body;
  
  console.log(`Token registration request:`, { username, token: token?.substring(0, 20) + '...' });
  
  if (!username || !token) {
    console.log('Token registration failed: missing username or token');
    return res.status(400).json({ error: 'Username and token are required' });
  }
  
  // Store token for user
  if (!userTokens.has(username)) {
    userTokens.set(username, new Set());
  }
  
  const userTokenSet = userTokens.get(username);
  if (userTokenSet.has(token)) {
    console.log(`Token already registered for user: ${username}`);
  } else {
    userTokenSet.add(token);
    console.log(`New token registered for user: ${username}`);
    // Save immediately after new registration
    try {
      saveTokens();
    } catch (saveError) {
      console.error('Failed to persist tokens to disk:', saveError);
    }
  }
  
  console.log(`Total tokens for ${username}: ${userTokenSet.size}`);
  console.log(`Total registered users: ${userTokens.size}`);
  
  res.json({ success: true, message: 'Token registered successfully' });
});

// Send notification to all other users
app.post('/send-notification', async (req, res) => {
  const { fromUser, title, body } = req.body;
  
  if (!fromUser || !title || !body) {
    return res.status(400).json({ error: 'fromUser, title, and body are required' });
  }
  
  if (!admin.apps.length) {
    return res.status(500).json({ error: 'Firebase Admin not initialized' });
  }
  
  try {
    let totalRecipients = 0;
    const promises = [];
    
    // Send to all users except the sender
    for (const [username, tokens] of userTokens.entries()) {
      if (username === fromUser) continue; // Skip sender
      
      for (const token of tokens) {
        const message = {
          token: token,
          notification: {
            title: title,
            body: body
          },
          webpush: {
            headers: {
              'Urgency': 'high'
            },
            notification: {
              icon: '/icon-192.png',
              badge: '/icon-192.png',
              tag: 'fcm-test'
            },
            fcm_options: {
              link: '/'
            }
          },
          android: {
            priority: 'high',
            notification: {
              sound: 'default',
              click_action: '/'
            }
          },
          apns: {
            payload: {
              aps: {
                sound: 'default',
                badge: 1
              }
            }
          }
        };
        
        promises.push(
          admin.messaging().send(message)
            .then(() => {
              console.log(`Notification sent to ${username} successfully`);
              totalRecipients++;
            })
            .catch((error) => {
              console.error(`Error sending notification to ${username}:`, error);
              // Remove invalid token
              if (error.code === 'messaging/registration-token-not-registered') {
                tokens.delete(token);
              }
            })
        );
      }
    }
    
    await Promise.all(promises);
    
    res.json({ 
      success: true, 
      recipients: totalRecipients,
      message: `Notification sent to ${totalRecipients} recipient(s)`
    });
    
  } catch (error) {
    console.error('Error sending notifications:', error);
    res.status(500).json({ error: 'Failed to send notifications' });
  }
});

// Get all registered users (for debugging)
app.get('/users', (req, res) => {
  const users = {};
  console.log('Current userTokens map:', userTokens);
  console.log('Number of registered users:', userTokens.size);
  
  for (const [username, tokens] of userTokens.entries()) {
    users[username] = {
      tokenCount: tokens.size,
      tokens: Array.from(tokens)
    };
  }
  res.json(users);
});

// Debug endpoint to check server status
app.get('/debug', (req, res) => {
  res.json({
    firebaseAdminInitialized: admin.apps.length > 0,
    registeredUsers: userTokens.size,
    userTokens: Object.fromEntries(
      Array.from(userTokens.entries()).map(([user, tokens]) => [user, {
        count: tokens.size,
        tokens: Array.from(tokens)
      }])
    ),
    timestamp: new Date().toISOString()
  });
});

// Start server
app.listen(PORT, '0.0.0.0', () => {
  console.log(`FCM Test PWA server running on port ${PORT}`);
  console.log(`Open http://localhost:${PORT} in your browser`);
  console.log(`Server listening on all interfaces (0.0.0.0:${PORT})`);
});
