const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const compression = require('compression');
const path = require('path');
require('dotenv').config();

// Enhanced logging setup
const winston = require('winston');
const morgan = require('morgan');

// Create logger with multiple transports
const logger = winston.createLogger({
  level: 'debug',
  format: winston.format.combine(
    winston.format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss'
    }),
    winston.format.errors({ stack: true }),
    winston.format.json(),
    winston.format.prettyPrint()
  ),
  defaultMeta: { service: 'reconnectifly-backend' },
  transports: [
    // Write all logs to console with colors
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple(),
        winston.format.printf(({ timestamp, level, message, service, ...meta }) => {
          return `${timestamp} [${service}] ${level}: ${message} ${Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''}`;
        })
      )
    }),
    
    // Write all logs to file
    new winston.transports.File({ 
      filename: 'logs/error.log', 
      level: 'error',
      format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json()
      )
    }),
    
    // Write all logs to combined file
    new winston.transports.File({ 
      filename: 'logs/combined.log',
      format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json()
      )
    })
  ],
});

// Create logs directory if it doesn't exist
const fs = require('fs');
if (!fs.existsSync('logs')) {
  fs.mkdirSync('logs');
}

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

// Enhanced middleware setup
app.use(compression());

// Enhanced CORS with debugging
app.use(cors({
  origin: function (origin, callback) {
    logger.debug(`CORS request from origin: ${origin}`);
    // Allow requests with no origin (mobile apps, etc.)
    if (!origin) return callback(null, true);
    
    const allowedOrigins = [
      'http://localhost:3000',
      'http://localhost:5500',
      'http://127.0.0.1:3000',
      'http://127.0.0.1:5500',
      'capacitor://localhost',
      'ionic://localhost',
      'http://localhost',
      'http://localhost:8080',
      'http://localhost:4200'
    ];
    
    if (allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      logger.warn(`CORS blocked request from origin: ${origin}`);
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With']
}));

// Enhanced request logging
const morganFormat = ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" - :response-time ms';
app.use(morgan(morganFormat, {
  stream: {
    write: (message) => {
      logger.info(message.trim());
    }
  }
}));

// Enhanced body parsing with size limits
app.use(express.json({ 
  limit: '50mb',
  verify: (req, res, buf) => {
    logger.debug(`Request body size: ${buf.length} bytes`);
  }
}));
app.use(express.urlencoded({ 
  extended: true, 
  limit: '50mb' 
}));

// API Request/Response debugging middleware
app.use((req, res, next) => {
  const start = Date.now();
  
  logger.debug(`📥 [${req.method}] ${req.url}`, {
    headers: req.headers,
    query: req.query,
    body: req.method === 'POST' || req.method === 'PUT' ? req.body : undefined,
    ip: req.ip,
    userAgent: req.get('User-Agent')
  });

  // Override res.json to log responses
  const originalJson = res.json;
  res.json = function(data) {
    const duration = Date.now() - start;
    logger.debug(`📤 [${req.method}] ${req.url} - ${res.statusCode} (${duration}ms)`, {
      statusCode: res.statusCode,
      responseSize: JSON.stringify(data).length,
      responseTime: `${duration}ms`,
      data: data
    });
    return originalJson.call(this, data);
  };

  next();
});

// Enhanced MongoDB connection with debugging
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/reconnectifly', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  serverSelectionTimeoutMS: 5000,
  bufferMaxEntries: 0,
  bufferCommands: false,
})
.then(() => {
  logger.info('✅ MongoDB connected successfully');
})
.catch((error) => {
  logger.error('❌ MongoDB connection failed:', error);
  process.exit(1);
});

// MongoDB connection event listeners
mongoose.connection.on('connected', () => {
  logger.info('🔗 MongoDB connection established');
});

mongoose.connection.on('error', (err) => {
  logger.error('❌ MongoDB connection error:', err);
});

mongoose.connection.on('disconnected', () => {
  logger.warn('⚠️ MongoDB disconnected');
});

// Enhanced error handling middleware
app.use((err, req, res, next) => {
  logger.error('🚨 Unhandled Error:', {
    error: err.message,
    stack: err.stack,
    url: req.url,
    method: req.method,
    body: req.body,
    query: req.query,
    headers: req.headers
  });

  res.status(err.status || 500).json({
    success: false,
    message: err.message || 'Internal Server Error',
    error: process.env.NODE_ENV === 'development' ? err.stack : undefined,
    timestamp: new Date().toISOString(),
    path: req.url,
    method: req.method
  });
});

// Import routes with debugging
logger.info('📁 Loading routes...');

// Load all route files with error handling
const routeFiles = [
  'routes/authRoutes',
  'routes/adminAuthRoutes',
  'routes/userRoutes',
  'routes/careerRoutes',
  'routes/examRoutes',
  'routes/quizRoutes',
  'routes/studyGroupRoutes',
  'routes/freeEducationRoutes',
  'routes/personalDetailsRoutes',
  'routes/schoolDetailsRoutes',
  'routes/portfolioRoutes',
  'routes/certificationRoutes',
  'routes/mentorRoutes',
  'routes/newsRoutes',
  'routes/postRoutes',
  'routes/businessRoutes'
];

routeFiles.forEach(routeFile => {
  try {
    const route = require(`./${routeFile}`);
    const routePath = routeFile.replace('routes/', '/api/');
    app.use(routePath, route);
    logger.info(`✅ Loaded route: ${routePath}`);
  } catch (error) {
    logger.error(`❌ Failed to load route ${routeFile}:`, error);
  }
});

// Health check endpoint with detailed info
app.get('/api/health', (req, res) => {
  const healthInfo = {
    status: 'OK',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    memory: process.memoryUsage(),
    version: process.version,
    environment: process.env.NODE_ENV || 'development',
    mongodb: mongoose.connection.readyState === 1 ? 'Connected' : 'Disconnected',
    port: PORT
  };
  
  logger.info('🏥 Health check requested', healthInfo);
  res.json({
    success: true,
    message: 'Server is healthy',
    data: healthInfo
  });
});

// Enhanced 404 handler
app.use('*', (req, res) => {
  logger.warn(`🔍 404 - Route not found: ${req.method} ${req.originalUrl}`, {
    url: req.originalUrl,
    method: req.method,
    ip: req.ip,
    userAgent: req.get('User-Agent')
  });
  
  res.status(404).json({
    success: false,
    message: 'Route not found',
    path: req.originalUrl,
    method: req.method,
    timestamp: new Date().toISOString()
  });
});

// Enhanced server startup
const server = app.listen(PORT, () => {
  logger.info(`🚀 Debug server running on port ${PORT}`);
  logger.info(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
  logger.info(`🔗 Health check: http://localhost:${PORT}/api/health`);
  logger.info(`📝 Logs directory: ./logs/`);
  logger.info(`🐛 Debug mode: ENABLED`);
});

// Enhanced server error handling
server.on('error', (error) => {
  logger.error('🚨 Server error:', error);
});

// Graceful shutdown
process.on('SIGTERM', () => {
  logger.info('🛑 SIGTERM received, shutting down gracefully');
  server.close(() => {
    logger.info('✅ Server closed');
    mongoose.connection.close(false, () => {
      logger.info('✅ MongoDB connection closed');
      process.exit(0);
    });
  });
});

process.on('SIGINT', () => {
  logger.info('🛑 SIGINT received, shutting down gracefully');
  server.close(() => {
    logger.info('✅ Server closed');
    mongoose.connection.close(false, () => {
      logger.info('✅ MongoDB connection closed');
      process.exit(0);
    });
  });
});

// Unhandled promise rejection handler
process.on('unhandledRejection', (reason, promise) => {
  logger.error('🚨 Unhandled Promise Rejection:', {
    reason: reason,
    promise: promise
  });
});

// Uncaught exception handler
process.on('uncaughtException', (error) => {
  logger.error('🚨 Uncaught Exception:', error);
  process.exit(1);
});

module.exports = app;
