import 'dotenv/config';
import express from 'express';
import session from 'express-session';
import MySQLStoreFactory from 'express-mysql-session';
import flash from 'connect-flash';
import methodOverride from 'method-override';
import expressLayouts from 'express-ejs-layouts';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import rateLimit from 'express-rate-limit';

import passport from './src/auth/passport.js';
import { pool } from './src/db/index.js';

import authRoutes from './src/routes/auth.js';
import dashboardRoutes from './src/routes/dashboard.js';
import angkatanRoutes from './src/routes/angkatan.js';
import kelasRoutes from './src/routes/kelas.js';
import santriRoutes from './src/routes/santri.js';
import userRoutes from './src/routes/user.js';
import undanganRoutes from './src/routes/undangan.js';
import sendRoutes from './src/routes/send.js';
import auditRoutes from './src/routes/audit.js';
import publicRoutes from './src/routes/public.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const app = express();

app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'src/views'));
app.use(expressLayouts);
app.set('layout', 'layouts/main');

app.use(express.json({ limit: '2mb' }));
app.use(express.urlencoded({ extended: true, limit: '2mb' }));
app.use(methodOverride('_method'));
app.use(express.static(path.join(__dirname, 'public')));

const MySQLStore = MySQLStoreFactory(session);
const sessionStore = new MySQLStore({
  createDatabaseTable: false,
  schema: {
    tableName: 'sessions',
    columnNames: { session_id: 'session_id', expires: 'expires', data: 'data' },
  },
}, pool);

app.use(
  session({
    secret: process.env.SESSION_SECRET || 'change-me',
    resave: false,
    saveUninitialized: false,
    store: sessionStore,
    cookie: {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'lax',
      maxAge: 1000 * 60 * 60 * 24 * 7, // 7 hari
    },
  }),
);

app.use(flash());
app.use(passport.initialize());
app.use(passport.session());

// Locals untuk semua view
app.use((req, res, next) => {
  res.locals.user = req.user || null;
  res.locals.flashSuccess = req.flash('success');
  res.locals.flashError = req.flash('error');
  res.locals.appName = 'Tasyakuran NFBS';
  res.locals.currentPath = req.path;
  res.locals.googleEnabled = Boolean(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET);
  next();
});

// Rate limit khusus login
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 10,
  message: 'Terlalu banyak percobaan login. Coba lagi 15 menit.',
});

// Routes
app.use('/', publicRoutes); // halaman undangan publik /:angkatan/:slug
app.use('/auth', loginLimiter, authRoutes);
// Alias /login langsung ke form login
app.get('/login', (req, res) => res.redirect('/auth/login'));
app.use('/dashboard', dashboardRoutes);
app.use('/angkatan', angkatanRoutes);
app.use('/kelas', kelasRoutes);
app.use('/santri', santriRoutes);
app.use('/users', userRoutes);
app.use('/undangan', undanganRoutes);
app.use('/send', sendRoutes);
app.use('/audit', auditRoutes);

app.get('/', (req, res) => {
  if (req.user) return res.redirect('/dashboard');
  res.redirect('/login');
});

app.use((req, res) => {
  res.status(404).render('error', { title: 'Not Found', message: 'Halaman tidak ditemukan.' });
});

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).render('error', { title: 'Error', message: err.message || 'Terjadi kesalahan server.' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`🚀 Tasyakuran NFBS running at http://localhost:${PORT}`);
});

export default app;
