require('dotenv').config();

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

const { initDB } = require('./config/database');
const { errorHandler, notFoundHandler } = require('./middleware/errorHandler');

const authRoutes = require('./routes/auth.routes');
const materiRoutes = require('./routes/materi.routes');
const risalahRoutes = require('./routes/risalah.routes');
const beritaRoutes = require('./routes/berita.routes');
const galeriRoutes = require('./routes/galeri.routes');
const konsultasiRoutes = require('./routes/konsultasi.routes');
const donasiRoutes = require('./routes/donasi.routes');
const programRoutes = require('./routes/program.routes');
const usersRoutes = require('./routes/users.routes');
const newsletterRoutes = require('./routes/newsletter.routes');
const settingsRoutes = require('./routes/settings.routes');
const logsRoutes = require('./routes/logs.routes');
const dashboardRoutes = require('./routes/dashboard.routes');
const translateRoutes = require('./routes/translate.routes');
const uploadRoutes = require('./routes/upload.routes');
const prayerRoutes = require('./routes/prayer.routes');

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

app.use(helmet({
  contentSecurityPolicy: false,
  crossOriginEmbedderPolicy: false,
  crossOriginResourcePolicy: false,
}));

const allowedOrigins = (process.env.CORS_ORIGIN || 'http://localhost:5173')
  .split(',')
  .map(origin => origin.trim())
  .filter(Boolean);

app.use(cors({
  origin(origin, callback) {
    if (!origin || allowedOrigins.includes(origin)) {
      return callback(null, true);
    }
    return callback(new Error('Tidak diizinkan oleh CORS'), false);
  },
  credentials: true
}));

const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 10,
  skipSuccessfulRequests: true,
  standardHeaders: true,
  legacyHeaders: false,
  message: { success: false, message: 'Terlalu banyak percobaan login, coba lagi nanti.' }
});

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

app.use((req, res, next) => {
  res.setHeader('Permissions-Policy', 'geolocation=(self), camera=(), microphone=()');
  next();
});

app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

app.use('/api/auth', authLimiter, authRoutes);
app.use('/api/materi', materiRoutes);
app.use('/api/risalah', risalahRoutes);
app.use('/api/berita', beritaRoutes);
app.use('/api/galeri', galeriRoutes);
app.use('/api/konsultasi', konsultasiRoutes);
app.use('/api/donasi', donasiRoutes);
app.use('/api/program', programRoutes);
app.use('/api/users', usersRoutes);
app.use('/api/newsletter', newsletterRoutes);
app.use('/api/settings', settingsRoutes);
app.use('/api/logs', logsRoutes);
app.use('/api/dashboard', dashboardRoutes);
app.use('/api/translate', translateRoutes);
app.use('/api/upload', uploadRoutes);
app.use('/api/prayer', prayerRoutes);

app.get('/api/health', (req, res) => {
  res.json({ status: 'ok', version: '2.1.0', time: new Date().toISOString() });
});

app.use('/src', express.static(path.join(__dirname, 'src')));
app.use(express.static(path.join(__dirname, 'dist')));

app.get('*', (req, res, next) => {
  if (req.path.startsWith('/api/') || req.path.startsWith('/uploads/') || req.path.startsWith('/src/')) {
    return next();
  }
  return res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});

app.use(notFoundHandler);
app.use(errorHandler);

async function startServer() {
  if (global.__NURALILM_SERVER_STARTED__) {
    return global.__NURALILM_SERVER_INSTANCE__;
  }

  global.__NURALILM_SERVER_STARTED__ = true;

  try {
    await initDB();
    global.__NURALILM_SERVER_INSTANCE__ = app.listen(PORT, '0.0.0.0', () => {
      console.log(`Nuralilm API Server running on port ${PORT}`);
      console.log(`CORS allowed: ${allowedOrigins.join(', ')}`);
      console.log('Helmet security headers: ACTIVE');
      console.log('Rate limiting: ACTIVE');
    });

    return global.__NURALILM_SERVER_INSTANCE__;
  } catch (err) {
    global.__NURALILM_SERVER_STARTED__ = false;
    console.error('Failed to initialize database:', err);
    throw err;
  }
}

startServer().catch(() => {
  process.exitCode = 1;
});

module.exports = app;
