const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const { globalErrorHandler } = require('./middleware/errorHandler');

const experimentsRouter = require('./routes/experiments');
const animalsRouter = require('./routes/animals');
const dailyStatusesRouter = require('./routes/dailyStatuses');
const auditLogsRouter = require('./routes/auditLogs');
const analysesRouter = require('./routes/analyses');
const sessionFilesRouter = require('./routes/sessionFiles');

const app = express();

// Security headers
app.use(helmet({
  crossOriginResourcePolicy: { policy: 'cross-origin' },
}));

// CORS — restrict to the configured frontend origin in production
const allowedOrigin = process.env.CORS_ORIGIN || '*';
app.use(cors({
  origin: allowedOrigin,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

// Rate limiting — 100 requests per minute per IP on all API routes
const apiLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 100,
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many requests, please try again later.' },
  skip: () => process.env.NODE_ENV === 'test',
});

app.use(express.json({ limit: '1mb' }));
app.use(morgan(process.env.NODE_ENV === 'test' ? 'silent' : process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));

// Health check (no rate limit)
app.get('/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date().toISOString() });
});

// DB info — returns database timezone (no rate limit)
const prisma = require('./lib/prisma');
app.get('/api/info', async (req, res) => {
  try {
    const [{ timezone }] = await prisma.$queryRaw`SELECT current_setting('TimeZone') AS timezone`;
    res.json({ dbTimezone: timezone });
  } catch {
    res.json({ dbTimezone: null });
  }
});

// Apply rate limiter to all API routes
app.use('/api', apiLimiter);

app.use('/api/experiments', experimentsRouter);
app.use('/api/animals', animalsRouter);
app.use('/api/daily-statuses', dailyStatusesRouter);
app.use('/api/audit-logs', auditLogsRouter);
app.use('/api', analysesRouter);
app.use('/api', sessionFilesRouter);

app.use((req, res) => {
  res.status(404).json({ error: `Route ${req.method} ${req.path} not found` });
});

app.use(globalErrorHandler);

module.exports = app;
