/**
 * ========================================
 * RUTAS DE REGISTRO DE ACTIVIDAD
 * ========================================
 *
 * Maneja el registro de actividades completadas por los usuarios.
 * TODAS las rutas requieren autenticación.
 * Los usuarios solo pueden ver/modificar sus propios registros.
 */

const express = require('express');
const router = express.Router();
const pool = require('../config/db');
const handleValidation = require('../middleware/handleValidation');
const { requireAuth } = require('../utils/jwt');
const { checkPermission } = require('../middleware/checkPermission');
const { RESOURCES, ACTIONS } = require('../config/permissions');

const {
  createRegistroValidator,
  updateRegistroValidator,
  registroIdValidator,
  listRegistrosValidator,
  finishRegistroValidator,
} = require('../validators/registroActividad.validators');

/**
 * ========================================
 * POST /api/registroactividad/start
 * ========================================
 * Inicia una nueva actividad para el usuario autenticado
 *
 * Body: { id_actividad: number }
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de CREATE en recurso ACTIVITY_LOG
 * - ✅ Usa id_usuario del token
 */
router.post('/start', requireAuth, checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.CREATE), async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const { id_actividad } = req.body;

    if (!id_actividad) {
      return res.status(400).json({ error: 'Falta id_actividad' });
    }

    // Bloquear si ya fue realizada por este usuario (tabla de estado)
    const [done] = await pool.query(
      `SELECT 1
         FROM usuario_actividad_estado
        WHERE id_usuario = ? AND id_actividad = ? AND estado = 'realizada'
        LIMIT 1`,
      [id_usuario, id_actividad]
    );
    if (done.length) {
      return res.status(409).json({ error: 'Esta actividad ya fue realizada por el usuario' });
    }

    const [result] = await pool.query(
      `INSERT INTO registro_actividad
         (id_usuario, id_actividad, fecha_inicio, completada)
       VALUES (?, ?, NOW(), 0)`,
      [id_usuario, id_actividad]
    );

    return res.status(201).json({ ok: true, id_registro: result.insertId });
  } catch (e) {
    console.error('POST /registroactividad/start', e);
    return res.status(500).json({ error: 'Error al iniciar registro' });
  }
});

/**
 * ========================================
 * PATCH /api/registroactividad/finish/:id
 * ========================================
 * Finaliza una actividad en progreso
 *
 * Body opcional: { emocion?, puntos_obtenidos?, comentario? }
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de UPDATE en recurso ACTIVITY_LOG
 * - ✅ Solo permite finalizar registros propios
 */
router.patch(
  '/finish/:id',
  requireAuth,
  checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.UPDATE),
  finishRegistroValidator,
  handleValidation,
  async (req, res) => {
    try {
      const { id_usuario } = req.user;
      const { id } = req.params;
      const {
        emocion = null,
        puntos_obtenidos = null,
        comentario = null,
      } = req.body || {};

      // Actualiza el registro (solo del usuario autenticado)
      const [r] = await pool.query(
        `UPDATE registro_actividad
            SET fecha_fin = COALESCE(fecha_fin, NOW()),
                emocion = COALESCE(?, emocion),
                puntos_obtenidos = COALESCE(?, puntos_obtenidos),
                comentario = COALESCE(?, comentario),
                completada = 1
          WHERE id_registro = ? AND id_usuario = ?`,
        [emocion, puntos_obtenidos, comentario, id, id_usuario]
      );

      if (r.affectedRows === 0) {
        return res.status(404).json({ error: 'Registro no encontrado' });
      }

      // Obtener la actividad de ese registro para marcar estado global del usuario
      const [[reg]] = await pool.query(
        `SELECT id_actividad
           FROM registro_actividad
          WHERE id_registro = ? AND id_usuario = ?`,
        [id, id_usuario]
      );
      if (!reg) {
        return res.status(404).json({ error: 'Registro no encontrado' });
      }

      // UPSERT en usuario_actividad_estado ➜ realizada
      await pool.query(
        `INSERT INTO usuario_actividad_estado (id_usuario, id_actividad, estado, fecha_realizada)
         VALUES (?, ?, 'realizada', NOW())
         ON DUPLICATE KEY UPDATE
           estado = 'realizada',
           fecha_realizada = COALESCE(usuario_actividad_estado.fecha_realizada, NOW())`,
        [id_usuario, reg.id_actividad]
      );

      return res.json({ ok: true });
    } catch (e) {
      console.error('PATCH /registroactividad/finish/:id', e);
      return res.status(500).json({ error: 'Error al finalizar registro' });
    }
  }
);

/**
 * ========================================
 * GET /api/registroactividad
 * ========================================
 * Lista los registros del usuario autenticado con filtros opcionales
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de LIST en recurso ACTIVITY_LOG
 * - ✅ Solo muestra registros del usuario autenticado (ignora user_id del query)
 */
router.get('/', requireAuth, checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.LIST), listRegistrosValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user; // ✅ Del token
    const { actividad_id, completada, desde, hasta } = req.query;

    let sql = `
      SELECT id_registro, id_usuario, id_actividad, fecha_inicio, fecha_fin,
             emocion, completada, puntos_obtenidos, comentario
        FROM registro_actividad
       WHERE id_usuario = ?`; // ✅ Siempre filtrar por usuario autenticado
    const params = [id_usuario];

    if (actividad_id) {
      const actId = Number(actividad_id);
      if (isNaN(actId)) return res.status(400).json({ error: 'actividad_id debe ser número' });
      sql += ' AND id_actividad = ?';
      params.push(actId);
    }
    if (completada !== undefined) {
      sql += ' AND completada = ?';
      params.push(Number(completada));
    }
    if (desde) { sql += ' AND fecha_inicio >= ?'; params.push(desde); }
    if (hasta) { sql += ' AND fecha_inicio <= ?'; params.push(hasta); }

    sql += ' ORDER BY id_registro DESC';

    const [rows] = await pool.query(sql, params);
    res.json({ ok: true, data: rows });
  } catch (e) {
    console.error('GET /registroactividad error:', e);
    res.status(500).json({ error: 'Error al listar registros' });
  }
});

/**
 * ========================================
 * GET /api/registroactividad/:id
 * ========================================
 * Obtiene un registro específico del usuario autenticado
 *
 * SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de READ en recurso ACTIVITY_LOG
 */
router.get('/:id', requireAuth, checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.READ), registroIdValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const id = Number(req.params.id);

    if (isNaN(id) || id <= 0) {
      return res.status(400).json({ error: 'ID de registro inválido' });
    }

    // ✅ Solo permite ver registros propios
    const [rows] = await pool.query(
      'SELECT * FROM registro_actividad WHERE id_registro = ? AND id_usuario = ?',
      [id, id_usuario]
    );

    if (!rows.length) {
      return res.status(404).json({ error: 'Registro no encontrado' });
    }

    res.json({ ok: true, data: rows[0] });
  } catch (e) {
    console.error('GET /registroactividad/:id error:', e);
    res.status(500).json({ error: 'Error al obtener registro' });
  }
});

/**
 * ========================================
 * POST /api/registroactividad
 * ========================================
 * Crea un nuevo registro de actividad para el usuario autenticado
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de CREATE en recurso ACTIVITY_LOG
 * - ✅ Usa id_usuario del token (NO del body)
 */
router.post('/', requireAuth, checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.CREATE), createRegistroValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user; // ✅ Del token, no del body
    const {
      id_actividad, fecha_inicio = null,
      emocion = null, completada = 0, puntos_obtenidos = 0, comentario = null
    } = req.body;

    // ✅ Validar que la actividad exista
    const [actExists] = await pool.query(
      'SELECT 1 FROM actividades WHERE id_actividad = ?',
      [id_actividad]
    );
    if (!actExists.length) {
      return res.status(400).json({ error: 'Actividad no existe' });
    }

    let sql, params;
    if (fecha_inicio) {
      sql = `
        INSERT INTO registro_actividad
          (id_usuario, id_actividad, fecha_inicio, emocion, completada, puntos_obtenidos, comentario)
        VALUES (?, ?, ?, ?, ?, ?, ?)`;
      params = [id_usuario, id_actividad, fecha_inicio, emocion, completada, puntos_obtenidos, comentario];
    } else {
      sql = `
        INSERT INTO registro_actividad
          (id_usuario, id_actividad, emocion, completada, puntos_obtenidos, comentario)
        VALUES (?, ?, ?, ?, ?, ?)`;
      params = [id_usuario, id_actividad, emocion, completada, puntos_obtenidos, comentario];
    }

    const [ins] = await pool.query(sql, params);
    res.status(201).json({ ok: true, message: 'Registro creado', id: ins.insertId });
  } catch (e) {
    console.error('POST /registroactividad error:', e);
    res.status(500).json({ error: 'Error al crear registro' });
  }
});

/**
 * ========================================
 * PUT /api/registroactividad/:id
 * ========================================
 * Actualiza un registro del usuario autenticado
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de UPDATE en recurso ACTIVITY_LOG
 * - ✅ Solo permite actualizar registros propios
 * - ✅ NO permite cambiar id_usuario
 */
router.put('/:id', requireAuth, checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.UPDATE), updateRegistroValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const id = Number(req.params.id);

    if (isNaN(id) || id <= 0) {
      return res.status(400).json({ error: 'ID de registro inválido' });
    }

    const {
      id_actividad, fecha_inicio, fecha_fin,
      emocion, completada, puntos_obtenidos, comentario,
    } = req.body;

    // ✅ Construir update dinámico (SIN id_usuario)
    const updates = {};
    if (id_actividad !== undefined) updates.id_actividad = id_actividad;
    if (fecha_inicio !== undefined) updates.fecha_inicio = fecha_inicio;
    if (fecha_fin !== undefined) updates.fecha_fin = fecha_fin;
    if (emocion !== undefined) updates.emocion = emocion;
    if (completada !== undefined) updates.completada = completada;
    if (puntos_obtenidos !== undefined) updates.puntos_obtenidos = puntos_obtenidos;
    if (comentario !== undefined) updates.comentario = comentario;

    if (Object.keys(updates).length === 0) {
      return res.status(400).json({ error: 'Nada para actualizar' });
    }

    const sets = Object.keys(updates).map(k => `${k} = ?`).join(', ');
    const values = [...Object.values(updates), id, id_usuario];

    // ✅ Solo actualiza si pertenece al usuario
    const [r] = await pool.query(
      `UPDATE registro_actividad SET ${sets} WHERE id_registro = ? AND id_usuario = ?`,
      values
    );

    if (r.affectedRows === 0) {
      return res.status(404).json({ error: 'Registro no encontrado o no autorizado' });
    }

    res.json({ ok: true, message: 'Registro actualizado' });
  } catch (e) {
    console.error('PUT /registroactividad/:id error:', e);
    res.status(500).json({ error: 'Error al actualizar registro' });
  }
});

/**
 * ========================================
 * DELETE /api/registroactividad/:id
 * ========================================
 * Elimina un registro del usuario autenticado
 *
 * SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de DELETE en recurso ACTIVITY_LOG
 */
router.delete('/:id', requireAuth, checkPermission(RESOURCES.ACTIVITY_LOG, ACTIONS.DELETE), registroIdValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const id = Number(req.params.id);

    if (isNaN(id) || id <= 0) {
      return res.status(400).json({ error: 'ID de registro inválido' });
    }

    // ✅ Solo elimina si pertenece al usuario
    const [r] = await pool.query(
      'DELETE FROM registro_actividad WHERE id_registro = ? AND id_usuario = ?',
      [id, id_usuario]
    );

    if (r.affectedRows === 0) {
      return res.status(404).json({ error: 'Registro no encontrado o no autorizado' });
    }

    res.json({ ok: true, message: 'Registro eliminado' });
  } catch (e) {
    console.error('DELETE /registroactividad/:id error:', e);
    res.status(500).json({ error: 'Error al eliminar registro' });
  }
});

module.exports = router;