require('dotenv').config();
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');
const WebSocket = require('ws');
const authRoutes = require('./routes/authRoutes');
const userRoutes = require('./routes/userRoutes');
const postRoutes = require('./routes/postRoutes'); 
const cellGroupRoutes = require('./routes/cellGroupRoutes'); 
const generalRoutes = require('./routes/generalRoutes');  
const messageRoutes = require('./routes/messageRoutes'); 
const paymentsRoutes = require('./routes/paymentsRoutes'); 
const errorHandler = require('./middleware/errorMiddleware');

const app = express();

// Middleware
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use((req, res, next) => {
  console.log(`Incoming: ${req.method} ${req.originalUrl}`); 
  next();
});
// Update all route prefixes to include /ppg
app.use('/ppg/api/auth', authRoutes);
app.use('/ppg/api', userRoutes);
app.use('/ppg/api', postRoutes);
app.use('/ppg/api', cellGroupRoutes);
app.use('/ppg/api', generalRoutes);
app.use('/ppg/api', messageRoutes);
app.use('/ppg/api', paymentsRoutes);

// Update your static files route
app.use('/ppg/uploads', express.static(path.join(__dirname, 'uploads')));

// 404 Handler
app.use((req, res) => {
  res.status(404).json({ 
    success: false,
    message: "Endpoint not found",
    requestedUrl: req.originalUrl
  });
});

// Error handling middleware
app.use(errorHandler);

// Start server
const PORT = process.env.PORT || 3000;
const server = app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

// Increase timeout to 10 minutes
server.timeout = 600000;

// WebSocket Server Implementation
const wss = new WebSocket.Server({ server });

// Store connected clients
const clients = new Map();

// WebSocket connection handler
wss.on('connection', (ws, req) => {
  console.log('New WebSocket connection');

  // Extract token from query parameters
  const token = req.url.split('token=')[1];
  
  // In a real application, you would verify the JWT token here
  // For now, we'll assume the client sends userId after authentication
  ws.on('message', (message) => {
    try {
      const data = JSON.parse(message);
      
      if (data.type === 'register' && data.userId) {
        // Associate WebSocket connection with user ID
        clients.set(data.userId.toString(), ws);
        console.log(`User ${data.userId} registered for WebSocket notifications`);
        
        // Send confirmation
        ws.send(JSON.stringify({
          type: 'connection',
          status: 'success',
          message: 'WebSocket connection established'
        }));
      }
    } catch (error) {
      console.error('Error parsing WebSocket message:', error);
    }
  });

  // Handle client disconnection
  ws.on('close', () => {
    // Remove disconnected client
    for (const [userId, clientWs] of clients.entries()) {
      if (clientWs === ws) {
        clients.delete(userId);
        console.log(`User ${userId} disconnected from WebSocket`);
        break;
      }
    }
  });

  // Handle errors
  ws.on('error', (error) => {
    console.error('WebSocket error:', error);
  });
});

// Make WebSocket server available to other modules
app.locals.wss = wss;
app.locals.clients = clients;

// WebSocket heartbeat to keep connections alive
setInterval(() => {
  wss.clients.forEach((client) => {
    if (client.readyState === WebSocket.OPEN) {
      client.ping();
    }
  });
}, 30000); // 30 seconds

module.exports = app;