const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const multer = require('multer');
const { getDb, logAudit } = require('../db');
const {
  collectStats,
  formatBytes,
  createBackup,
  listBackups,
  getBackupPath,
  deleteBackup,
  restoreBackup,
  getPaths
} = require('../lib/backup');

function requireAdmin(req, res, next) {
  const db = getDb();
  const user = db.prepare('SELECT * FROM users WHERE id = ?').get(req.session.userId);
  if (!user || user.role !== 'admin') return res.status(403).render('404', { path: req.path });
  next();
}

const uploadDir = path.join(getPaths().dataDir, 'backups', 'uploads-tmp');
if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true });

const upload = multer({
  dest: uploadDir,
  limits: { fileSize: 500 * 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    if (file.originalname.endsWith('.tar.gz') || file.originalname.endsWith('.tgz') || file.mimetype === 'application/gzip') {
      cb(null, true);
    } else {
      cb(new Error('Alleen .tar.gz backupbestanden'));
    }
  }
});

router.get('/', requireAdmin, (req, res) => {
  const stats = collectStats();
  const backups = listBackups();
  const disk = getPaths();
  let diskFree = null;
  try {
    const { execSync } = require('child_process');
    const out = execSync(`df -B1 "${disk.dataDir}" 2>/dev/null | tail -1`, { encoding: 'utf8' });
    const parts = out.trim().split(/\s+/);
    if (parts.length >= 4) diskFree = formatBytes(parseInt(parts[3], 10));
  } catch (e) { /* ignore */ }

  res.render('backup', {
    stats,
    backups,
    diskFree,
    formatBytes,
    restored: req.query.restored === '1',
    created: req.query.created === '1',
    deleted: req.query.deleted === '1',
    error: req.query.error || null,
    user: { username: req.session.username }
  });
});

router.post('/create', requireAdmin, (req, res) => {
  try {
    const backup = createBackup();
    logAudit(req.session.userId, req.session.username, 'backup_create', 'system', 0, backup.filename);
    if (req.query.download === '1') {
      return res.download(backup.path, backup.filename);
    }
    res.redirect('/backup?created=1');
  } catch (e) {
    console.error('Backup create error:', e);
    res.redirect('/backup?error=' + encodeURIComponent('Backup mislukt: ' + e.message));
  }
});

router.get('/download/:filename', requireAdmin, (req, res) => {
  const p = getBackupPath(req.params.filename);
  if (!p) return res.redirect('/backup?error=' + encodeURIComponent('Backup niet gevonden'));
  logAudit(req.session.userId, req.session.username, 'backup_download', 'system', 0, req.params.filename);
  res.download(p, req.params.filename);
});

router.post('/delete/:filename', requireAdmin, (req, res) => {
  try {
    if (!deleteBackup(req.params.filename)) {
      return res.redirect('/backup?error=' + encodeURIComponent('Backup niet gevonden'));
    }
    logAudit(req.session.userId, req.session.username, 'backup_delete', 'system', 0, req.params.filename);
    res.redirect('/backup?deleted=1');
  } catch (e) {
    res.redirect('/backup?error=' + encodeURIComponent(e.message));
  }
});

router.post('/restore', requireAdmin, upload.single('backup_file'), (req, res) => {
  if (!req.file) {
    return res.redirect('/backup?error=' + encodeURIComponent('Geen bestand geüpload'));
  }
  try {
    const result = restoreBackup(req.file.path);
    fs.unlinkSync(req.file.path);
    logAudit(req.session.userId, req.session.username, 'backup_restore', 'system', 0, JSON.stringify(result));
    res.redirect('/backup?restored=1');
  } catch (e) {
    console.error('Restore error:', e);
    try { fs.unlinkSync(req.file.path); } catch (err) { /* ignore */ }
    res.redirect('/backup?error=' + encodeURIComponent('Herstel mislukt: ' + e.message));
  }
});

router.post('/restore/:filename', requireAdmin, (req, res) => {
  const p = getBackupPath(req.params.filename);
  if (!p) return res.redirect('/backup?error=' + encodeURIComponent('Backup niet gevonden'));
  try {
    const result = restoreBackup(p);
    logAudit(req.session.userId, req.session.username, 'backup_restore', 'system', 0, req.params.filename);
    res.redirect('/backup?restored=1');
  } catch (e) {
    res.redirect('/backup?error=' + encodeURIComponent('Herstel mislukt: ' + e.message));
  }
});

module.exports = router;
