const express = require('express');
const http = require('http');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const rateLimit = require('rate-limiter-flexible');
require('dotenv').config();

const logger = require('./utils/logger');
const connectDB = require('./config/database');
const authRoutes = require('./routes/auth');
const serverRoutes = require('./routes/servers');
const modsRoutes = require('./routes/mods');
const { errorHandler, notFound } = require('./middleware/errorHandler');

// Override console.error to properly log error objects
const originalConsoleError = console.error;
console.error = (...args) => {
  args.forEach(arg => {
    if (arg instanceof Error) {
      logger.error('Console Error:', {
        message: arg.message,
        stack: arg.stack,
        name: arg.name
      });
    } else if (typeof arg === 'object' && arg !== null) {
      logger.error('Console Error Object:', arg);
    } else {
      logger.error('Console Error:', arg);
    }
  });
};

const app = express();
const server = http.createServer(app);

// Middleware
app.use(helmet());
app.use(compression());
app.use(cors({
  origin: ["https://galaxystrike.online", "https://api.korvarix.com", "http://api.korvarix.com:3001"],
  credentials: true
}));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// Static file serving
app.use(express.static('../Website/dist'));

// Rate limiting
const { RateLimiterMemory } = require('rate-limiter-flexible');
const limiter = new RateLimiterMemory({
  keyGenerator: (req) => req.ip,
  points: 100, // limit each IP to 100 requests per windowMs
  duration: 900, // 15 minutes
  blockDuration: 900, // Block for 15 minutes
});
app.use('/api/', async (req, res, next) => {
  try {
    const resLimiter = await limiter.consume(req.ip);
    if (!resLimiter.remainingPoints) {
      return res.status(429).json({ error: 'Too many requests, please try again later.' });
    }
    next();
  } catch (error) {
    next();
  }
});

// Routes - API Server Only (Auth + Server Browser + Mods)
app.use('/api/auth', authRoutes);
app.use('/api/servers', serverRoutes);
app.use('/api/mods', modsRoutes);

// Health check
app.get('/health', (req, res) => {
  res.status(200).json({ 
    status: 'API Server OK', 
    service: 'galaxystrikeonline-api',
    timestamp: new Date().toISOString(),
    uptime: process.uptime()
  });
});

// API version endpoint
app.get('/api/ssc/version', (req, res) => {
  res.status(200).json({ 
    version: '1.0.0',
    service: 'galaxystrikeonline-api',
    timestamp: new Date().toISOString()
  });
});

// Fallback route for SPA - only serve index.html for non-API routes
app.get('*', (req, res) => {
  // Don't try to serve index.html for API routes
  if (req.path.startsWith('/api/')) {
    return res.status(404).json({ error: 'API endpoint not found' });
  }
  
  // Try dist first (for built files), fallback to public (for development)
  const distPath = require('path').resolve(__dirname, '../dist/index.html');
  const publicPath = require('path').resolve(__dirname, '../public/index.html');
  
  const fs = require('fs');
  if (fs.existsSync(distPath)) {
    res.sendFile(distPath);
  } else if (fs.existsSync(publicPath)) {
    res.sendFile(publicPath);
  } else {
    res.status(404).json({ error: 'Frontend not found' });
  }
});

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

// Initialize database only (no game systems for API server)
async function startServer() {
  try {
    // Connect to database
    await connectDB();
    logger.info('Database connected successfully');

    // Start API server
    const PORT = process.env.PORT || 3001;
    server.listen(PORT, () => {
      logger.info(`API Server running on port ${PORT}`);
      logger.info('API Server handles: Authentication, Server Browser, User Data');
    });
  } catch (error) {
    logger.error('Failed to start API server:', error);
    process.exit(1);
  }
}

// Handle uncaught errors
process.on('uncaughtException', (error) => {
  logger.error('Uncaught Exception:', error);
});

process.on('unhandledRejection', (reason, promise) => {
  logger.error('Unhandled Rejection at:', promise, 'reason:', reason);
});

// Handle HTTP server errors
server.on('error', (error) => {
  logger.error('HTTP Server error:', error);
});

startServer();

module.exports = { app, server };
