// src/routes/notificaciones.routes.js
const express = require('express');
const router = express.Router();

const pool = require('../config/db');
const handleValidation = require('../middleware/handleValidation');

const {
  createNotiValidator,
  updateNotiValidator,
  notiIdValidator,
  listNotiValidator,
  markIdValidator,
} = require('../validators/notificaciones.validators');

// LISTAR
router.get('/', listNotiValidator, handleValidation, async (req, res) => {
  const { user_id, estado, canal, tipo, desde, hasta, solo_pendientes } = req.query;

  let sql = `
    SELECT id_notificacion, id_usuario, tipo, titulo, cuerpo, canal,
           programada_para, enviada_en, leida_en, estado, meta
      FROM notificaciones
     WHERE 1=1`;
  const params = [];

  if (user_id) { sql += ' AND id_usuario = ?'; params.push(Number(user_id)); }
  if (estado)  { sql += ' AND estado = ?'; params.push(estado); }
  if (canal)   { sql += ' AND canal = ?'; params.push(canal); }
  if (tipo)    { sql += ' AND tipo = ?'; params.push(tipo); }
  if (desde)   { sql += ' AND programada_para >= ?'; params.push(desde); }
  if (hasta)   { sql += ' AND programada_para <= ?'; params.push(hasta); }
  if (solo_pendientes === '1') { sql += ' AND estado IN ("programada")'; }

  sql += ' ORDER BY COALESCE(programada_para, creada_en) DESC, id_notificacion DESC';

  try {
    const [rows] = await pool.query(sql, params);
    res.json(rows);
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al listar notificaciones' });
  }
});

// DETALLE
router.get('/:id', notiIdValidator, handleValidation, async (req, res) => {
  try {
    const [rows] = await pool.query(
      'SELECT * FROM notificaciones WHERE id_notificacion = ?',
      [req.params.id]
    );
    if (!rows.length) return res.status(404).json({ error: 'Notificación no encontrada' });
    res.json(rows[0]);
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al obtener notificación' });
  }
});

// CREAR
router.post('/', createNotiValidator, handleValidation, async (req, res) => {
  const {
    id_usuario, tipo, titulo, cuerpo, canal,
    programada_para, meta = null, estado = 'programada'
  } = req.body;

  try {
    const [result] = await pool.query(
      `INSERT INTO notificaciones
        (id_usuario, tipo, titulo, cuerpo, canal, programada_para, estado, meta)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
      [id_usuario, tipo, titulo, cuerpo, canal, programada_para, estado, meta]
    );
    res.status(201).json({ message: 'Notificación creada', id: result.insertId });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al crear notificación' });
  }
});

// ACTUALIZAR (parcial)
router.put('/:id', updateNotiValidator, handleValidation, async (req, res) => {
  const { id } = req.params;
  const {
    id_usuario = null, tipo = null, titulo = null, cuerpo = null, canal = null,
    programada_para = null, meta = null, estado = null
  } = req.body;

  try {
    const [result] = await pool.query(
      `UPDATE notificaciones
          SET id_usuario = COALESCE(?, id_usuario),
              tipo = COALESCE(?, tipo),
              titulo = COALESCE(?, titulo),
              cuerpo = COALESCE(?, cuerpo),
              canal = COALESCE(?, canal),
              programada_para = COALESCE(?, programada_para),
              meta = COALESCE(?, meta),
              estado = COALESCE(?, estado)
        WHERE id_notificacion = ?`,
      [id_usuario, tipo, titulo, cuerpo, canal, programada_para, meta, estado, id]
    );
    if (result.affectedRows === 0) return res.status(404).json({ error: 'Notificación no encontrada' });
    res.json({ message: 'Notificación actualizada' });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al actualizar notificación' });
  }
});

// MARCAR COMO ENVIADA (set enviada_en = NOW(), estado='enviada')
router.patch('/:id/enviar', markIdValidator, handleValidation, async (req, res) => {
  try {
    const [result] = await pool.query(
      `UPDATE notificaciones
          SET enviada_en = NOW(),
              estado = 'enviada'
        WHERE id_notificacion = ?`,
      [req.params.id]
    );
    if (result.affectedRows === 0) return res.status(404).json({ error: 'Notificación no encontrada' });
    res.json({ message: 'Notificación marcada como enviada' });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al marcar enviada' });
  }
});

// MARCAR COMO LEÍDA (set leida_en = NOW(), estado='leida')
router.patch('/:id/leer', markIdValidator, handleValidation, async (req, res) => {
  try {
    const [result] = await pool.query(
      `UPDATE notificaciones
          SET leida_en = NOW(),
              estado = 'leida'
        WHERE id_notificacion = ?`,
      [req.params.id]
    );
    if (result.affectedRows === 0) return res.status(404).json({ error: 'Notificación no encontrada' });
    res.json({ message: 'Notificación marcada como leída' });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al marcar leída' });
  }
});

// ELIMINAR
router.delete('/:id', notiIdValidator, handleValidation, async (req, res) => {
  try {
    const [result] = await pool.query(
      'DELETE FROM notificaciones WHERE id_notificacion = ?',
      [req.params.id]
    );
    if (result.affectedRows === 0) return res.status(404).json({ error: 'Notificación no encontrada' });
    res.json({ message: 'Notificación eliminada' });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Error al eliminar notificación' });
  }
});

module.exports = router;
