'use strict';

const path = require('node:path');
const express = require('express');
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');
const { rateLimit } = require('express-rate-limit');
const config = require('./src/config');
const { pool } = require('./src/db');
const authRoutes = require('./src/routes/auth-routes');
const adminRoutes = require('./src/routes/admin-routes');
const custodyRoutes = require('./src/routes/custody-routes');
const { startBackupScheduler } = require('./src/backup');

const app = express();
if (config.isProduction) app.set('trust proxy', 1);
app.disable('x-powered-by');

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'"],
      imgSrc: ["'self'", 'data:'],
      fontSrc: ["'self'"],
      connectSrc: ["'self'"],
      objectSrc: ["'none'"],
      frameAncestors: ["'none'"],
      baseUri: ["'self'"],
      formAction: ["'self'"],
    },
  },
  crossOriginResourcePolicy: { policy: 'same-origin' },
  referrerPolicy: { policy: 'no-referrer' },
}));
app.use(compression());
app.use(morgan(config.isProduction ? 'combined' : 'dev'));
app.use(express.json({ limit: '3mb' }));
app.use(express.urlencoded({ extended: false, limit: '100kb' }));

app.use('/api', (_req, res, next) => {
  res.setHeader('Cache-Control', 'no-store');
  next();
});

const userLoginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  limit: 12,
  standardHeaders: 'draft-8',
  legacyHeaders: false,
  message: { message: 'محاولات دخول كثيرة. انتظر قليلًا ثم أعد المحاولة.' },
});
const adminLoginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  limit: 8,
  standardHeaders: 'draft-8',
  legacyHeaders: false,
  message: { message: 'محاولات دخول الأدمن كثيرة. انتظر قليلًا ثم أعد المحاولة.' },
});
app.use('/api/auth/login', userLoginLimiter);
app.use('/api/auth/admin/login', adminLoginLimiter);

app.get('/api/health', async (_req, res) => {
  try {
    await pool.query('SELECT 1');
    res.json({ ok: true, app: config.appName });
  } catch (_) {
    res.status(503).json({ ok: false, message: 'قاعدة البيانات غير متاحة.' });
  }
});
app.use('/api/auth', authRoutes);
app.use('/api/admin', adminRoutes);
app.use('/api', custodyRoutes);

app.use(express.static(path.join(config.rootDir, 'public'), {
  etag: true,
  lastModified: true,
  maxAge: config.isProduction ? '1h' : 0,
  setHeaders(res, filePath) {
  if (filePath.endsWith('.html')) {
    res.setHeader('Cache-Control', 'no-store');
  }

  if (filePath.endsWith('.css')) {
    res.setHeader('Content-Type', 'text/css; charset=utf-8');
    res.setHeader('Cache-Control', 'no-store');
  }

  if (filePath.endsWith('.js')) {
    res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
    res.setHeader('Cache-Control', 'no-store');
  }
},
}));

app.use('/api', (_req, res) => res.status(404).json({ message: 'المسار غير موجود.' }));
app.use((error, _req, res, _next) => {
  console.error(error);
  if (error.code === 'ER_DUP_ENTRY') return res.status(409).json({ message: 'اسم المستخدم مستخدم مسبقًا.' });
  const status = error.statusCode || 500;
  const message = status >= 500 ? 'حدث خطأ داخلي. لم يتم حفظ أي بيانات ناقصة.' : error.message;
  return res.status(status).json({ message });
});

async function start() {
  try {
    await pool.query('SELECT 1');
   const server = app.listen(config.port, '0.0.0.0', () => {
      console.log(`${config.appName} يعمل على المنفذ ${config.port}`);
      startBackupScheduler();
    });
    const shutdown = async () => {
      server.close(async () => {
        await pool.end();
        process.exit(0);
      });
      setTimeout(() => process.exit(1), 10_000).unref();
    };
    process.on('SIGTERM', shutdown);
    process.on('SIGINT', shutdown);
  } catch (error) {
    console.error('تعذر تشغيل النظام. تأكد من ملف .env وتجهيز قاعدة البيانات:', error.message);
    process.exit(1);
  }
}

if (require.main === module) start();
module.exports = app;

