const express = require('express');
const router = express.Router();
const { getDb } = require('../db');
const { parseDiagramJson, DIAGRAM_TYPE_LABELS } = require('../lib/rack-diagram');

router.get('/designer', (req, res) => {
  const db = getDb();
  const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
  const clientId = req.query.client_id || req.session.activeClientId || null;
  const host = process.env.BASE_URL || `http://${req.hostname}:3000`;
  const designerBase = host.replace(':3000', ':3001') + '/python-editor/';
  res.render('designer-embed', { clients, clientId, designerUrl: designerBase });
});

router.get('/', (req, res) => {
  const db = getDb();
  const { search, client_id, diagram_type } = req.query;

  let sql = `SELECT d.*, c.name as client_name,
    json_array_length(d.nodes) as node_count
    FROM data_diagrams d JOIN clients c ON c.id = d.client_id WHERE 1=1`;
  const params = [];

  if (search) {
    sql += ` AND (d.name LIKE ? OR d.description LIKE ?)`;
    params.push(`%${search}%`, `%${search}%`);
  }
  if (client_id) {
    sql += ` AND d.client_id = ?`;
    params.push(client_id);
  }
  if (diagram_type) {
    sql += ` AND d.diagram_type = ?`;
    params.push(diagram_type);
  }

  sql += ` ORDER BY d.updated_at DESC`;

  const diagrams = db.prepare(sql).all(...params);
  const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
  res.render('arch-list', { diagrams, clients, filters: req.query });
});

router.get('/new', (req, res) => {
  const db = getDb();
  const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
  res.render('arch-editor', { diagram: null, clients, clientId: null, rack: null, rackDevices: [], linkedDiagrams: [], defaultDiagramType: null, error: null });
});

router.get('/new/:clientId', (req, res) => {
  const db = getDb();
  const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
  res.render('arch-editor', { diagram: null, clients, clientId: parseInt(req.params.clientId), rack: null, rackDevices: [], linkedDiagrams: [], defaultDiagramType: null, error: null });
});

router.post('/save', (req, res) => {
  const db = getDb();
  const { id, client_id, name, description, diagram_type, nodes, edges, rack_id } = req.body;
  if (!name || !client_id) return res.status(400).json({ error: 'Name and client required' });

  if (id) {
    db.prepare("UPDATE data_diagrams SET name=?, description=?, diagram_type=?, nodes=?, edges=?, rack_id=?, updated_at=datetime('now') WHERE id=?")
      .run(name, description, diagram_type || 'data_architecture', nodes || '[]', edges || '[]', rack_id || null, id);
    res.json({ id: parseInt(id, 10) });
  } else {
    const result = db.prepare('INSERT INTO data_diagrams (client_id, name, description, diagram_type, nodes, edges, rack_id) VALUES (?,?,?,?,?,?,?)')
      .run(client_id, name, description, diagram_type || 'data_architecture', nodes || '[]', edges || '[]', rack_id || null);
    res.json({ id: result.lastInsertRowid });
  }
});

router.get('/:id', (req, res) => {
  const db = getDb();
  const diagram = db.prepare('SELECT d.*, c.name as client_name FROM data_diagrams d JOIN clients c ON c.id = d.client_id WHERE d.id = ?').get(req.params.id);
  if (!diagram) return res.redirect('/architecture');
  if (diagram.rack_id && !req.query.embed && req.query.stay !== '1') {
    return res.redirect('/racks/' + diagram.rack_id + '/diagram/' + diagram.id);
  }
  const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
  let rack = null;
  let rackDevices = [];
  let linkedDiagrams = [];
  let flowDiagram = null;
  let landscapeDiagram = null;
  if (diagram.rack_id) {
    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(diagram.rack_id);
    rackDevices = db.prepare('SELECT * FROM rack_devices WHERE rack_id = ? ORDER BY position_u ASC').all(diagram.rack_id);
    linkedDiagrams = db.prepare('SELECT id, name, diagram_type FROM data_diagrams WHERE rack_id = ?').all(diagram.rack_id);
    flowDiagram = linkedDiagrams.find(d => d.diagram_type === 'application_flow') || null;
    landscapeDiagram = linkedDiagrams.find(d => d.diagram_type === 'application_landscape') || null;
  }
  const { getWorkspaceTab } = require('../lib/rack-diagram');
  res.render('arch-editor', {
    diagram,
    clients,
    clientId: diagram.client_id,
    rack,
    rackDevices,
    linkedDiagrams,
    flowDiagram,
    landscapeDiagram,
    defaultDiagramType: null,
    workspaceTab: rack ? getWorkspaceTab(diagram.diagram_type) : null,
    embed: req.query.embed === '1',
    error: null
  });
});

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

router.get('/report/:id', (req, res) => {
  const db = getDb();
  const diagram = db.prepare('SELECT d.*, c.name as client_name FROM data_diagrams d JOIN clients c ON c.id = d.client_id WHERE d.id = ?').get(req.params.id);
  if (!diagram) return res.redirect('/architecture');
  if (diagram.rack_id) return res.redirect('/racks/' + diagram.rack_id + '/report');

  let nodes = JSON.parse(diagram.nodes);
  let edges = JSON.parse(diagram.edges);

  if (!Array.isArray(nodes) && nodes && nodes.nodes) { edges = nodes.edges || []; nodes = nodes.nodes || []; }
  if (!Array.isArray(edges) && edges && edges.nodes) { nodes = edges.nodes || []; edges = edges.edges || []; }

  const typeCount = {};
  const vendorCount = {};
  nodes.forEach(n => {
    typeCount[n.type ? n.type.split('-')[0] : 'other'] = (typeCount[n.type ? n.type.split('-')[0] : 'other'] || 0) + 1;
    if (n.vendor) vendorCount[n.vendor] = (vendorCount[n.vendor] || 0) + 1;
  });

  res.render('arch-report', { diagram, nodes, edges, typeCount, vendorCount });
});

router.get('/render/: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: 'not found' });

  let nodes = JSON.parse(diagram.nodes);
  let edges = JSON.parse(diagram.edges);

  // Handle legacy Python-editor format: nodes/edges columns store {"nodes":[...],"edges":[...]}
  if (!Array.isArray(nodes) && nodes && nodes.nodes) {
    edges = nodes.edges || [];
    nodes = nodes.nodes || [];
  }
  if (!Array.isArray(edges) && edges && edges.nodes) {
    nodes = edges.nodes || [];
    edges = edges.edges || [];
  }

  res.json({
    name: diagram.name,
    description: diagram.description,
    diagram_type: diagram.diagram_type,
    nodes,
    edges
  });
});

module.exports = router;
