// src/routes/categorias.routes.js
const express = require('express');
const router = express.Router();
const pool = require('../config/db');
const { requireAuth } = require('../utils/jwt'); // ✅ CAMBIO: verifyToken → requireAuth
const requireAdmin = require('../middleware/requireAdmin');
const handleValidation = require('../middleware/handleValidation');

const {
  createCategoriaValidator,
  updateCategoriaValidator,
  listCategoriasValidator
} = require('../validators/categorias.validators');

/** =========================
 *  Rutas públicas/estudiante
 *  ========================= */
// Listar categorías (público/estudiante)
router.get('/', listCategoriasValidator, handleValidation, async (req, res, next) => {
  try {
    const { page = 1, limit = 20, q = '' } = req.query;
    const offset = (page - 1) * limit;
    const where = q ? 'WHERE nombre LIKE ?' : '';
    const params = q ? [`%${q}%`, +limit, +offset] : [+limit, +offset];

    const [rows] = await pool.query(
      `SELECT id_categoria, nombre, descripcion, activo
       FROM categorias
       ${where}
       ORDER BY id_categoria DESC
       LIMIT ? OFFSET ?`,
      params
    );

    const [[{ total }]] = await pool.query(
      `SELECT COUNT(*) AS total FROM categorias ${q ? 'WHERE nombre LIKE ?' : ''}`,
      q ? [`%${q}%`] : []
    );

    res.json({ data: rows, page: +page, limit: +limit, total });
  } catch (err) { next(err); }
});

/** =========================
 *  Rutas ADMIN (no afectan estudiante)
 *  ========================= */

// Crear categoría (solo ADMIN)
router.post('/',
  requireAuth, requireAdmin(), // ✅ CAMBIO: verifyToken → requireAuth
  createCategoriaValidator, handleValidation,
  async (req, res, next) => {
    try {
      const { nombre, descripcion = null, activo = true } = req.body;

      // Evitar duplicados por nombre
      const [dup] = await pool.query(
        `SELECT 1 FROM categorias WHERE LOWER(nombre)=LOWER(?) LIMIT 1`,
        [nombre]
      );
      if (dup.length) return res.status(409).json({ error: 'La categoría ya existe' });

      const [r] = await pool.query(
        `INSERT INTO categorias (nombre, descripcion, activo) VALUES (?,?,?)`,
        [nombre, descripcion, activo ? 1 : 0]
      );
      const [row] = await pool.query(
        `SELECT id_categoria, nombre, descripcion, activo FROM categorias WHERE id_categoria=?`,
        [r.insertId]
      );
      res.status(201).json(row[0]);
    } catch (err) { next(err); }
  }
);

// Actualizar categoría (solo ADMIN)
router.put('/:id_categoria',
  requireAuth, requireAdmin(), // ✅ CAMBIO: verifyToken → requireAuth
  updateCategoriaValidator, handleValidation,
  async (req, res, next) => {
    try {
      const id = +req.params.id_categoria;

      // Si cambia nombre, verificar duplicados
      if (req.body.nombre !== undefined) {
        const [dup] = await pool.query(
          `SELECT 1 FROM categorias
           WHERE LOWER(nombre)=LOWER(?) AND id_categoria<>? LIMIT 1`,
          [req.body.nombre, id]
        );
        if (dup.length) return res.status(409).json({ error: 'Ya existe otra categoría con ese nombre' });
      }

      const fields = ['nombre','descripcion','activo'];
      const sets = [];
      const values = [];
      for (const f of fields) {
        if (req.body[f] !== undefined) {
          sets.push(`${f}=?`);
          values.push(f === 'activo' ? (req.body[f] ? 1 : 0) : req.body[f]);
        }
      }
      if (!sets.length) return res.status(400).json({ error: 'Nada para actualizar' });

      values.push(id);
      const [resUpd] = await pool.query(`UPDATE categorias SET ${sets.join(', ')} WHERE id_categoria=?`, values);
      if (resUpd.affectedRows === 0) return res.status(404).json({ error: 'Categoría no encontrada' });

      const [row] = await pool.query(
        `SELECT id_categoria, nombre, descripcion, activo FROM categorias WHERE id_categoria=?`,
        [id]
      );
      res.json(row[0]);
    } catch (err) { next(err); }
  }
);

// Eliminar categoría (solo ADMIN)
router.delete('/:id_categoria',
  requireAuth, requireAdmin(), // ✅ CAMBIO: verifyToken → requireAuth
  async (req, res, next) => {
    try {
      const id = +req.params.id_categoria;
      const [resDel] = await pool.query(`DELETE FROM categorias WHERE id_categoria=?`, [id]);
      if (resDel.affectedRows === 0) return res.status(404).json({ error: 'Categoría no encontrada' });
      res.status(204).end();
    } catch (err) { next(err); }
  }
);

module.exports = router;