const path = require('path');
// Load .env from backend/ regardless of current working directory (fixes missing JWT_SECRET → login 500)
require('dotenv').config({ path: path.join(__dirname, '..', '.env') });

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');

const { sequelize, testConnection } = require('./config/database');
const authRoutes = require('./routes/auth');
const chitGroupRoutes = require('./routes/chitGroups');
const memberRoutes = require('./routes/members');
const paymentRoutes = require('./routes/payments');
const phonePeRoutes = require('./routes/phonepe');
const transactionSyncRoutes = require('./routes/transactionSync');
const monthlyDrawRoutes = require('./routes/monthlyDraws');
const shareRoutes = require('./routes/share');
const publicShareRoutes = require('./routes/publicShare');
const notificationRoutes = require('./routes/notifications');
const ReminderService = require('./services/reminder-service');

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

// Behind Nginx: required for correct req.ip, HTTPS, PUBLIC_BASE_URL inference, and express-rate-limit.
// Must be a number (hop count), not `true` — express-rate-limit rejects trust proxy === true.
const _trustHops = Number.parseInt(process.env.TRUST_PROXY_HOPS || '1', 10);
app.set('trust proxy', Number.isFinite(_trustHops) && _trustHops >= 1 ? _trustHops : 1);

// Security middleware
app.use(helmet());

// CORS configuration
// - Development default: allow all
// - Production: configure allowed origins via ALLOWED_ORIGINS="https://app.example.com,https://admin.example.com"
const allowedOrigins = (process.env.ALLOWED_ORIGINS || '')
  .split(',')
  .map(s => s.trim())
  .filter(Boolean);

app.use(cors({
  origin: (origin, callback) => {
    if (!origin) return callback(null, true); // server-to-server / curl
    if (process.env.NODE_ENV !== 'production') return callback(null, true);
    if (allowedOrigins.length === 0) return callback(new Error('CORS: ALLOWED_ORIGINS not configured'), false);
    return callback(null, allowedOrigins.includes(origin));
  },
  credentials: false,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'Accept']
}));

// Rate limiting
const limiter = rateLimit({
  windowMs: Number.parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 15 * 60 * 1000, // 15 minutes
  max: Number.parseInt(process.env.RATE_LIMIT_MAX_REQUESTS, 10) || 300,
  message: 'Too many requests from this IP, please try again later.',
});
app.use('/api', limiter);

// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// Logging middleware
if (process.env.NODE_ENV === 'development') {
  app.use(morgan('dev'));
}

// Serve static files (for API tester)
app.use('/test', express.static('public'));

// Public share links (no auth)
app.use('/share', publicShareRoutes);

// Health check endpoint
app.get('/health', (req, res) => {
  res.json({
    success: true,
    message: 'LuckyChit API is running',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV
  });
});

// API routes
app.use('/api/auth', authRoutes);
app.use('/api/chit-groups', chitGroupRoutes);
app.use('/api/members', memberRoutes);
app.use('/api/payments', paymentRoutes);
app.use('/api/payments/phonepe', phonePeRoutes);
app.use('/api/transaction-sync', transactionSyncRoutes);
app.use('/api/monthly-draws', monthlyDrawRoutes);
app.use('/api/share', shareRoutes);
app.use('/api/notifications', notificationRoutes);

// 404 handler - removed for now to fix path-to-regexp issue
// app.use('/*', (req, res) => {
//   res.status(404).json({
//     success: false,
//     message: 'Route not found'
//   });
// });

// Global error handler
app.use((err, req, res, next) => {
  console.error('Global error handler:', err);
  
  res.status(err.status || 500).json({
    success: false,
    message: err.message || 'Internal server error',
    ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
  });
});

// Start server
const startServer = async () => {
  try {
    // Test database connection
    console.log('🔌 Attempting to connect to database...');
    await testConnection();
    
    // Database schema management:
    // - In production, do NOT auto-alter schema on boot.
    // - Use explicit migrations; if you must auto-sync, set DB_AUTO_SYNC=true explicitly.
    const autoSync = String(process.env.DB_AUTO_SYNC || '').toLowerCase() === 'true';
    const isSqlite = sequelize.getDialect() === 'sqlite';
    const shouldSync =
      process.env.NODE_ENV !== 'production' || autoSync || isSqlite;
    if (shouldSync) {
      console.log('🔄 Syncing database models...');
      // Never use alter on SQLite: Sequelize copies via *_backup tables with NOT NULL timestamps;
      // migrated rows with null created_at/updated_at → INSERT fails → crash loop (PM2 502).
      const alter =
        process.env.NODE_ENV !== 'production' && sequelize.getDialect() !== 'sqlite';
      await sequelize.sync({ alter });
      console.log('✅ Database models synchronized');
    } else {
      console.log('⚠️  Skipping sequelize.sync in production (set DB_AUTO_SYNC=true to override)');
    }
    
    // Start payment reminder scheduler
    console.log('⏰ Starting payment reminder scheduler...');
    ReminderService.startScheduler();
    
    // Start server
    app.listen(PORT, () => {
      console.log(`🚀 Server running on port ${PORT}`);
      console.log(`📊 Environment: ${process.env.NODE_ENV}`);
      console.log(`🔗 Health check: http://localhost:${PORT}/health`);
      console.log(`🔗 API base: http://localhost:${PORT}/api`);
      console.log(`📱 WhatsApp share: http://localhost:${PORT}/api/share`);
      console.log(`🔔 Notifications: http://localhost:${PORT}/api/notifications`);
    });
  } catch (error) {
    const d = sequelize.getDialect();
    console.error('❌ Server startup failed:', error.message);
    if (error.errors) console.error(error.errors.map((e) => e.message).join('; '));
    if (d === 'sqlite') {
      console.log('💡 SQLite: check SQLITE_STORAGE path, file permissions, and avoid sync alter with bad data.');
    } else {
      console.log('💡 Ensure the database is running and credentials in .env are correct.');
      console.log('💡 Create the DB if needed: CREATE DATABASE luckychit;');
    }
    process.exit(1);
  }
};

startServer();
