const express = require('express');
const router = express.Router();
const { getDb, logAudit } = require('../../db');

// ============ RACKS ============

router.get('/racks', (req, res) => {
  const db = getDb();
  res.json(db.prepare(`
    SELECT r.*, c.name as client_name,
      (SELECT COUNT(*) FROM rack_devices d WHERE d.rack_id = r.id) as device_count
    FROM racks r JOIN clients c ON c.id = r.client_id
    ORDER BY r.updated_at DESC
  `).all());
});

router.post('/racks', (req, res) => {
  const db = getDb();
  const { client_id, name, location, datacenter, total_units, notes } = req.body;
  if (!client_id || !name || !name.trim()) return res.status(400).json({ error: 'Client en naam zijn verplicht' });
  const result = db.prepare(`INSERT INTO racks (client_id, name, location, datacenter, total_units, notes)
    VALUES (?, ?, ?, ?, ?, ?)`).run(client_id, name.trim(), location || null, datacenter || null, total_units || 42, notes || null);
  logAudit(req.session.userId, req.session.username, 'rack_created', 'rack', result.lastInsertRowid, `Rack ${name} aangemaakt via SPA`);
  res.status(201).json({ id: result.lastInsertRowid });
});

router.get('/racks/:id', (req, res) => {
  const db = getDb();
  const rack = db.prepare('SELECT r.*, c.name as client_name FROM racks r JOIN clients c ON c.id = r.client_id WHERE r.id = ?').get(req.params.id);
  if (!rack) return res.status(404).json({ error: 'Rack niet gevonden' });
  res.json({
    rack,
    devices: db.prepare('SELECT * FROM rack_devices WHERE rack_id = ? ORDER BY position_u').all(req.params.id)
  });
});

router.put('/racks/:id', (req, res) => {
  const db = getDb();
  const { name, location, datacenter, total_units, notes } = req.body;
  if (!name || !name.trim()) return res.status(400).json({ error: 'Naam is verplicht' });
  db.prepare(`UPDATE racks SET name=?, location=?, datacenter=?, total_units=?, notes=?, updated_at=datetime('now') WHERE id=?`)
    .run(name, location, datacenter, total_units, notes, req.params.id);
  res.json({ ok: true });
});

router.delete('/racks/:id', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM racks WHERE id = ?').run(req.params.id);
  res.json({ ok: true });
});

// ---- Rack devices ----

router.post('/racks/:id/devices', (req, res) => {
  const db = getDb();
  const { name, device_type, model, manufacturer, position_u, height_u, specs, mgmt_ip, notes, serial, asset_tag, status } = req.body;
  if (!name || !name.trim() || !position_u) return res.status(400).json({ error: 'Naam en positie (U) zijn verplicht' });
  const result = db.prepare(`INSERT INTO rack_devices (rack_id, name, device_type, model, manufacturer, position_u, height_u, specs, mgmt_ip, notes, serial, asset_tag, status)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
    .run(req.params.id, name.trim(), device_type || 'server', model || null, manufacturer || null, position_u, height_u || 1,
      specs || null, mgmt_ip || null, notes || null, serial || '', asset_tag || '', status || 'active');
  logAudit(req.session.userId, req.session.username, 'rack_device_created', 'rack_device', result.lastInsertRowid, `Rack device ${name} aangemaakt via SPA`);
  res.status(201).json({ id: result.lastInsertRowid });
});

router.put('/racks/devices/:deviceId', (req, res) => {
  const db = getDb();
  const { name, device_type, model, manufacturer, position_u, height_u, specs, mgmt_ip, notes, serial, asset_tag, status } = req.body;
  db.prepare(`UPDATE rack_devices SET name=?, device_type=?, model=?, manufacturer=?, position_u=?, height_u=?, specs=?, mgmt_ip=?, notes=?, serial=?, asset_tag=?, status=?, updated_at=datetime('now') WHERE id=?`)
    .run(name, device_type, model, manufacturer, position_u, height_u, specs, mgmt_ip, notes, serial, asset_tag, status, req.params.deviceId);
  res.json({ ok: true });
});

router.delete('/racks/devices/:deviceId', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM rack_devices WHERE id = ?').run(req.params.deviceId);
  res.json({ ok: true });
});

// ============ NETWORK DEVICES ============

router.get('/networking/devices', (req, res) => {
  const db = getDb();
  res.json(db.prepare(`
    SELECT nd.*, c.name as client_name
    FROM network_devices nd JOIN clients c ON c.id = nd.client_id
    ORDER BY nd.updated_at DESC
  `).all());
});

router.post('/networking/devices', (req, res) => {
  const db = getDb();
  const { client_id, name, device_type, model, manufacturer, ip_address, mgmt_ip, ports_count, os_version, notes, status } = req.body;
  if (!client_id || !name || !name.trim() || !device_type) return res.status(400).json({ error: 'Client, naam en type zijn verplicht' });
  const result = db.prepare(`INSERT INTO network_devices (client_id, name, device_type, model, manufacturer, ip_address, mgmt_ip, ports_count, os_version, notes, status)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
    .run(client_id, name.trim(), device_type, model || null, manufacturer || null, ip_address || null, mgmt_ip || null,
      ports_count || 24, os_version || null, notes || null, status || 'active');
  logAudit(req.session.userId, req.session.username, 'network_device_created', 'network_device', result.lastInsertRowid, `Netwerkdevice ${name} aangemaakt via SPA`);
  res.status(201).json({ id: result.lastInsertRowid });
});

router.get('/networking/devices/:id', (req, res) => {
  const db = getDb();
  const device = db.prepare('SELECT nd.*, c.name as client_name FROM network_devices nd JOIN clients c ON c.id = nd.client_id WHERE nd.id = ?').get(req.params.id);
  if (!device) return res.status(404).json({ error: 'Netwerkdevice niet gevonden' });
  res.json({
    device,
    connections: db.prepare(`SELECT * FROM network_connections
      WHERE (from_type = 'network_device' AND from_id = ?) OR (to_type = 'network_device' AND to_id = ?)
      ORDER BY created_at DESC`).all(req.params.id, req.params.id)
  });
});

router.put('/networking/devices/:id', (req, res) => {
  const db = getDb();
  const { name, device_type, model, manufacturer, ip_address, mgmt_ip, ports_count, os_version, notes, status } = req.body;
  db.prepare(`UPDATE network_devices SET name=?, device_type=?, model=?, manufacturer=?, ip_address=?, mgmt_ip=?, ports_count=?, os_version=?, notes=?, status=?, updated_at=datetime('now') WHERE id=?`)
    .run(name, device_type, model, manufacturer, ip_address, mgmt_ip, ports_count, os_version, notes, status, req.params.id);
  res.json({ ok: true });
});

router.delete('/networking/devices/:id', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM network_devices WHERE id = ?').run(req.params.id);
  res.json({ ok: true });
});

// ============ NETWORK CONNECTIONS ============

router.get('/networking/connections', (req, res) => {
  const db = getDb();
  res.json(db.prepare(`
    SELECT nc.*, c.name as client_name
    FROM network_connections nc JOIN clients c ON c.id = nc.client_id
    ORDER BY nc.created_at DESC
  `).all());
});

router.post('/networking/connections', (req, res) => {
  const db = getDb();
  const { client_id, name, from_type, from_id, from_port, to_type, to_id, to_port, media_type, speed, vlan, status, notes } = req.body;
  if (!client_id || !from_type || !to_type) return res.status(400).json({ error: 'Client, bron- en doeltype zijn verplicht' });
  const result = db.prepare(`INSERT INTO network_connections (client_id, name, from_type, from_id, from_port, to_type, to_id, to_port, media_type, speed, vlan, status, notes)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
    .run(client_id, name || null, from_type, from_id || null, from_port || null, to_type, to_id || null, to_port || null,
      media_type || 'copper', speed || '1GbE', vlan || null, status || 'active', notes || null);
  logAudit(req.session.userId, req.session.username, 'network_connection_created', 'network_connection', result.lastInsertRowid, 'Netwerkverbinding aangemaakt via SPA');
  res.status(201).json({ id: result.lastInsertRowid });
});

router.put('/networking/connections/:id', (req, res) => {
  const db = getDb();
  const { name, from_type, from_id, from_port, to_type, to_id, to_port, media_type, speed, vlan, status, notes } = req.body;
  db.prepare(`UPDATE network_connections SET name=?, from_type=?, from_id=?, from_port=?, to_type=?, to_id=?, to_port=?, media_type=?, speed=?, vlan=?, status=?, notes=? WHERE id=?`)
    .run(name, from_type, from_id, from_port, to_type, to_id, to_port, media_type, speed, vlan, status, notes, req.params.id);
  res.json({ ok: true });
});

router.delete('/networking/connections/:id', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM network_connections WHERE id = ?').run(req.params.id);
  res.json({ ok: true });
});

// ============ DIAGRAMS ============

router.get('/diagrams', (req, res) => {
  const db = getDb();
  res.json(db.prepare(`
    SELECT d.id, d.client_id, d.name, d.description, d.diagram_type, d.engagement_id, d.rack_id, d.created_at, d.updated_at, c.name as client_name
    FROM data_diagrams d JOIN clients c ON c.id = d.client_id
    ORDER BY d.updated_at DESC
  `).all());
});

router.get('/diagrams/:id', (req, res) => {
  const db = getDb();
  const diagram = db.prepare('SELECT * FROM data_diagrams WHERE id = ?').get(req.params.id);
  if (!diagram) return res.status(404).json({ error: 'Diagram niet gevonden' });
  let nodes = [], edges = [];
  try { nodes = JSON.parse(diagram.nodes || '[]'); } catch (e) { nodes = []; }
  try { edges = JSON.parse(diagram.edges || '[]'); } catch (e) { edges = []; }
  res.json({ ...diagram, nodes, edges });
});

router.post('/diagrams', (req, res) => {
  const db = getDb();
  const { client_id, name, description, diagram_type, nodes, edges, engagement_id, rack_id } = req.body;
  if (!client_id || !name || !name.trim()) return res.status(400).json({ error: 'Client en naam zijn verplicht' });
  const result = db.prepare(`INSERT INTO data_diagrams (client_id, name, description, diagram_type, nodes, edges, engagement_id, rack_id)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
    .run(client_id, name.trim(), description || null, diagram_type || 'data_architecture',
      JSON.stringify(nodes || []), JSON.stringify(edges || []), engagement_id || null, rack_id || null);
  logAudit(req.session.userId, req.session.username, 'diagram_created', 'diagram', result.lastInsertRowid, `Diagram ${name} aangemaakt via SPA`);
  res.status(201).json({ id: result.lastInsertRowid });
});

router.put('/diagrams/:id', (req, res) => {
  const db = getDb();
  const { name, description, diagram_type, nodes, edges, engagement_id, rack_id } = req.body;
  db.prepare(`UPDATE data_diagrams SET name=?, description=?, diagram_type=?, nodes=?, edges=?, engagement_id=?, rack_id=?, updated_at=datetime('now') WHERE id=?`)
    .run(name, description, diagram_type, JSON.stringify(nodes || []), JSON.stringify(edges || []), engagement_id || null, rack_id || null, req.params.id);
  res.json({ ok: true });
});

router.delete('/diagrams/:id', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM data_diagrams WHERE id = ?').run(req.params.id);
  res.json({ ok: true });
});

module.exports = router;
