const express = require('express');
const { randomUUID } = require('crypto');
const { getDb, PLANTILLA_ENCUESTA } = require('../config/database');

const router = express.Router();

function rowToEncuesta(row) {
  return {
    id: row.id,
    titulo: row.titulo,
    departamentoId: row.departamento_id,
    departamento_id: row.departamento_id,
    descripcion: row.descripcion,
    preguntas: JSON.parse(row.preguntas),
    activa: row.activa === 1,
    creadoEn: row.creado_en,
    creado_en: row.creado_en,
    departamentoNombre: row.departamento_nombre || null,
  };
}

function rowToRespuesta(row) {
  return {
    id: row.id,
    encuestaId: row.encuesta_id,
    departamentoId: row.departamento_id,
    datos: JSON.parse(row.datos),
    respondidoPor: row.respondido_por,
    creadoEn: row.creado_en,
  };
}

router.get('/plantilla', (_req, res) => {
  res.json({ success: true, data: PLANTILLA_ENCUESTA });
});

router.get('/', (req, res) => {
  try {
    const db = getDb();
    const { departamento_id } = req.query;
    let sql = `
      SELECT e.*, o.nombre as departamento_nombre
      FROM encuestas e
      JOIN organizacion_nodos o ON o.id = e.departamento_id
      WHERE e.activa = 1
    `;
    const params = [];
    if (departamento_id) {
      sql += ' AND e.departamento_id = ?';
      params.push(departamento_id);
    }
    sql += ' ORDER BY o.nombre, e.titulo';
    const rows = db.prepare(sql).all(...params);
    res.json({ success: true, data: rows.map(rowToEncuesta) });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
});

router.get('/estadisticas', (_req, res) => {
  try {
    const db = getDb();
    const stats = db.prepare(`
      SELECT
        o.id as departamento_id,
        o.nombre as departamento_nombre,
        COUNT(DISTINCT e.id) as total_encuestas,
        COUNT(r.id) as total_respuestas,
        ROUND(AVG(CAST(json_extract(r.datos, '$.calificacionGeneral') AS REAL)), 2) as promedio_calificacion
      FROM organizacion_nodos o
      LEFT JOIN encuestas e ON e.departamento_id = o.id AND e.activa = 1
      LEFT JOIN respuestas r ON r.encuesta_id = e.id
      WHERE o.activo = 1
      GROUP BY o.id, o.nombre
      HAVING total_encuestas > 0 OR total_respuestas > 0
      ORDER BY o.nombre
    `).all();
    res.json({ success: true, data: stats });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
});

router.get('/:id', (req, res) => {
  try {
    const db = getDb();
    const row = db.prepare(`
      SELECT e.*, o.nombre as departamento_nombre
      FROM encuestas e
      JOIN organizacion_nodos o ON o.id = e.departamento_id
      WHERE e.id = ?
    `).get(req.params.id);
    if (!row) return res.status(404).json({ success: false, error: 'Encuesta no encontrada' });
    res.json({ success: true, data: rowToEncuesta(row) });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
});

router.post('/', (req, res) => {
  try {
    const db = getDb();
    const { titulo, departamento_id, descripcion, preguntas } = req.body;
    if (!titulo?.trim()) throw new Error('El título es obligatorio');
    if (!departamento_id) throw new Error('El departamento es obligatorio');

    const dept = db.prepare('SELECT id FROM organizacion_nodos WHERE id = ? AND activo = 1').get(departamento_id);
    if (!dept) throw new Error('Departamento no encontrado');

    const id = `encuesta-${randomUUID().slice(0, 8)}`;
    db.prepare(`
      INSERT INTO encuestas (id, titulo, departamento_id, descripcion, preguntas, activa)
      VALUES (?, ?, ?, ?, ?, 1)
    `).run(
      id,
      titulo.trim(),
      departamento_id,
      descripcion || null,
      JSON.stringify(preguntas || PLANTILLA_ENCUESTA)
    );

    const row = db.prepare(`
      SELECT e.*, o.nombre as departamento_nombre
      FROM encuestas e JOIN organizacion_nodos o ON o.id = e.departamento_id
      WHERE e.id = ?
    `).get(id);

    res.status(201).json({ success: true, data: rowToEncuesta(row) });
  } catch (error) {
    res.status(400).json({ success: false, error: error.message });
  }
});

router.put('/:id', (req, res) => {
  try {
    const db = getDb();
    const existing = db.prepare('SELECT * FROM encuestas WHERE id = ?').get(req.params.id);
    if (!existing) return res.status(404).json({ success: false, error: 'Encuesta no encontrada' });

    const { titulo, descripcion, preguntas, activa } = req.body;
    db.prepare(`
      UPDATE encuestas SET titulo = ?, descripcion = ?, preguntas = ?, activa = ?
      WHERE id = ?
    `).run(
      titulo ?? existing.titulo,
      descripcion ?? existing.descripcion,
      preguntas ? JSON.stringify(preguntas) : existing.preguntas,
      activa !== undefined ? (activa ? 1 : 0) : existing.activa,
      req.params.id
    );

    const row = db.prepare(`
      SELECT e.*, o.nombre as departamento_nombre
      FROM encuestas e JOIN organizacion_nodos o ON o.id = e.departamento_id
      WHERE e.id = ?
    `).get(req.params.id);

    res.json({ success: true, data: rowToEncuesta(row) });
  } catch (error) {
    res.status(400).json({ success: false, error: error.message });
  }
});

router.delete('/:id', (req, res) => {
  try {
    const db = getDb();
    const existing = db.prepare('SELECT * FROM encuestas WHERE id = ?').get(req.params.id);
    if (!existing) return res.status(404).json({ success: false, error: 'Encuesta no encontrada' });
    db.prepare('UPDATE encuestas SET activa = 0 WHERE id = ?').run(req.params.id);
    res.json({ success: true, data: { deleted: req.params.id } });
  } catch (error) {
    res.status(400).json({ success: false, error: error.message });
  }
});

router.get('/:id/respuestas', (req, res) => {
  try {
    const db = getDb();
    const rows = db.prepare(`
      SELECT * FROM respuestas WHERE encuesta_id = ? ORDER BY creado_en DESC
    `).all(req.params.id);
    res.json({ success: true, data: rows.map(rowToRespuesta) });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
});

router.post('/:id/respuestas', (req, res) => {
  try {
    const db = getDb();
    const encuesta = db.prepare('SELECT * FROM encuestas WHERE id = ? AND activa = 1').get(req.params.id);
    if (!encuesta) return res.status(404).json({ success: false, error: 'Encuesta no encontrada o inactiva' });

    const { datos, respondido_por } = req.body;
    if (!datos || typeof datos !== 'object') throw new Error('Los datos de respuesta son obligatorios');

    const preguntas = JSON.parse(encuesta.preguntas);
    for (const p of preguntas.filter((q) => q.required)) {
      if (datos[p.name] === undefined || datos[p.name] === null || datos[p.name] === '') {
        throw new Error(`El campo "${p.label}" es obligatorio`);
      }
    }

    const id = randomUUID();
    db.prepare(`
      INSERT INTO respuestas (id, encuesta_id, departamento_id, datos, respondido_por)
      VALUES (?, ?, ?, ?, ?)
    `).run(id, req.params.id, encuesta.departamento_id, JSON.stringify(datos), respondido_por || null);

    const row = db.prepare('SELECT * FROM respuestas WHERE id = ?').get(id);
    res.status(201).json({ success: true, data: rowToRespuesta(row) });
  } catch (error) {
    res.status(400).json({ success: false, error: error.message });
  }
});

module.exports = router;
