import express from 'express';
import helmet from 'helmet';
import cors from 'cors';
import rateLimit from 'express-rate-limit';
import { initDb, getAllCars, addCar, updateCar, deleteCar, replaceAllCars, verifyPassword } from './db.js';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

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

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
      fontSrc: ["'self'", "https://fonts.gstatic.com", "data:"],
      imgSrc: ["'self'", "data:", "blob:"],
      connectSrc: ["'self'"],
    },
  },
}));
app.use(cors());
app.use(express.json({ limit: '1mb' }));

const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 200,
  standardHeaders: true,
  legacyHeaders: false,
});
app.use('/api/', apiLimiter);

const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 10,
  standardHeaders: true,
  legacyHeaders: false,
});

initDb();

// Serve static frontend files
const distPath = join(__dirname, '..', 'dist');
app.use(express.static(distPath));

// API routes
app.get('/api/cars', (_req, res) => {
  const cars = getAllCars();
  res.json(cars);
});

app.post('/api/cars', (req, res) => {
  const { name, width, height, rearWidth, rearHeight } = req.body;
  if (!name || typeof width !== 'number' || typeof height !== 'number') {
    return res.status(400).json({ error: 'name, width en height zijn verplicht' });
  }
  if (width <= 0 || height <= 0) {
    return res.status(400).json({ error: 'width en height moeten positief zijn' });
  }
  if (rearWidth !== undefined && (typeof rearWidth !== 'number' || rearWidth <= 0)) {
    return res.status(400).json({ error: 'rearWidth moet een positief getal zijn' });
  }
  if (rearHeight !== undefined && (typeof rearHeight !== 'number' || rearHeight <= 0)) {
    return res.status(400).json({ error: 'rearHeight moet een positief getal zijn' });
  }
  const car = addCar({ name: String(name).trim(), width, height, rearWidth: rearWidth || null, rearHeight: rearHeight || null });
  res.status(201).json(car);
});

app.put('/api/cars/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const { name, width, height, rearWidth, rearHeight } = req.body;
  if (!name || typeof width !== 'number' || typeof height !== 'number') {
    return res.status(400).json({ error: 'name, width en height zijn verplicht' });
  }
  const car = updateCar(id, { name: String(name).trim(), width, height, rearWidth: rearWidth || null, rearHeight: rearHeight || null });
  if (!car) {
    return res.status(404).json({ error: 'Auto niet gevonden' });
  }
  res.json(car);
});

app.delete('/api/cars/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const deleted = deleteCar(id);
  if (!deleted) {
    return res.status(404).json({ error: 'Auto niet gevonden' });
  }
  res.json({ success: true });
});

app.put('/api/cars', (req, res) => {
  const cars = req.body;
  if (!Array.isArray(cars)) {
    return res.status(400).json({ error: 'Array van auto\'s verwacht' });
  }
  replaceAllCars(cars);
  res.json(getAllCars());
});

app.post('/api/auth/verify', authLimiter, (req, res) => {
  const { password } = req.body;
  if (!password) {
    return res.status(400).json({ error: 'Wachtwoord is verplicht' });
  }
  const valid = verifyPassword(password);
  res.json({ authenticated: valid });
});

// SPA fallback - serve index.html for all non-API routes
app.get('*', (_req, res) => {
  res.sendFile(join(distPath, 'index.html'));
});

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Kenteken Gen server draait op poort ${PORT}`);
});
