/**
 * ========================================
 * RUTAS DE METAS
 * ========================================
 *
 * Maneja las metas/objetivos de los usuarios.
 * TODAS las rutas requieren autenticación.
 * Los usuarios solo pueden ver/modificar sus propias metas.
 */

const express = require('express');
const router = express.Router();

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

const {
  createMetaValidator,
  updateMetaValidator,
  metaIdValidator,
  listMetasValidator,
} = require('../validators/metas.validators');

/**
 * ========================================
 * GET /api/metas
 * ========================================
 * Lista las metas del usuario autenticado con filtros opcionales
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de LIST en recurso GOALS
 * - ✅ Solo muestra metas del usuario autenticado (ignora user_id del query)
 * - ✅ Validación de estados y tipos permitidos
 */
router.get('/', requireAuth, checkPermission(RESOURCES.GOALS, ACTIONS.LIST), listMetasValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user; // ✅ Del token, no del query
    const { estado, tipo, categoria, desde, hasta } = req.query;

    // ✅ Validar estado si se proporciona
    const validEstados = ['activa', 'completada', 'cancelada'];
    if (estado && !validEstados.includes(estado)) {
      return res.status(400).json({ error: 'Estado inválido' });
    }

    // ✅ Validar tipo si se proporciona
    const validTipos = ['diaria', 'semanal', 'mensual'];
    if (tipo && !validTipos.includes(tipo)) {
      return res.status(400).json({ error: 'Tipo inválido' });
    }

    let sql = `
      SELECT id_meta, id_usuario, tipo, valor_objetivo, id_categoria,
             fecha_inicio, fecha_fin, estado, progreso_actual, creada_en
        FROM metas
       WHERE id_usuario = ?`; // ✅ Siempre filtrar por usuario autenticado
    const params = [id_usuario];

    if (estado) { sql += ' AND estado = ?'; params.push(estado); }
    if (tipo) { sql += ' AND tipo = ?'; params.push(tipo); }
    if (categoria) {
      const cat = Number(categoria);
      if (isNaN(cat)) return res.status(400).json({ error: 'categoria debe ser número' });
      sql += ' AND id_categoria = ?';
      params.push(cat);
    }
    if (desde) { sql += ' AND fecha_inicio >= ?'; params.push(desde); }
    if (hasta) { sql += ' AND fecha_inicio <= ?'; params.push(hasta); }

    sql += ' ORDER BY id_meta DESC';

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

/**
 * ========================================
 * GET /api/metas/:id
 * ========================================
 * Obtiene una meta específica del usuario autenticado
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de READ en recurso GOALS
 * - ✅ Solo permite ver metas propias (validación de ownership)
 */
router.get('/:id', requireAuth, checkPermission(RESOURCES.GOALS, ACTIONS.READ), metaIdValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const id = Number(req.params.id);

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

    // ✅ Solo permitir ver metas propias
    const [rows] = await pool.query(
      'SELECT * FROM metas WHERE id_meta = ? AND id_usuario = ?',
      [id, id_usuario]
    );

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

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

/**
 * ========================================
 * POST /api/metas
 * ========================================
 * Crea una nueva meta para el usuario autenticado
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de CREATE en recurso GOALS
 * - ✅ Usa id_usuario del token (NO del body)
 * - ✅ Validación de tipos y estados permitidos
 */
router.post('/', requireAuth, checkPermission(RESOURCES.GOALS, ACTIONS.CREATE), createMetaValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user; // ✅ Del token, no del body
    const {
      tipo, valor_objetivo, id_categoria = null,
      fecha_inicio, fecha_fin = null, estado = 'activa',
      progreso_actual = 0,
    } = req.body;

    // ✅ Validar tipo
    const validTipos = ['diaria', 'semanal', 'mensual'];
    if (!validTipos.includes(tipo)) {
      return res.status(400).json({ error: 'Tipo inválido. Debe ser: diaria, semanal o mensual' });
    }

    // ✅ Validar estado
    const validEstados = ['activa', 'completada', 'cancelada'];
    if (!validEstados.includes(estado)) {
      return res.status(400).json({ error: 'Estado inválido. Debe ser: activa, completada o cancelada' });
    }

    // ✅ Validar id_categoria si se proporciona
    if (id_categoria !== null) {
      const [catExists] = await pool.query(
        'SELECT 1 FROM categorias WHERE id_categoria = ?',
        [id_categoria]
      );
      if (!catExists.length) {
        return res.status(400).json({ error: 'Categoría no existe' });
      }
    }

    const [result] = await pool.query(
      `INSERT INTO metas
        (id_usuario, tipo, valor_objetivo, id_categoria, fecha_inicio, fecha_fin,
         estado, progreso_actual, creada_en)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())`,
      [id_usuario, tipo, valor_objetivo, id_categoria, fecha_inicio, fecha_fin, estado, progreso_actual]
    );

    res.status(201).json({ ok: true, message: 'Meta creada', id: result.insertId });
  } catch (e) {
    console.error('POST /metas error:', e);
    res.status(500).json({ error: 'Error al crear meta' });
  }
});

/**
 * ========================================
 * PUT /api/metas/:id
 * ========================================
 * Actualiza una meta del usuario autenticado
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de UPDATE en recurso GOALS
 * - ✅ Solo permite actualizar metas propias (ownership)
 * - ✅ NO permite cambiar id_usuario (eliminado COALESCE peligroso)
 * - ✅ Validación de estados y tipos
 */
router.put('/:id', requireAuth, checkPermission(RESOURCES.GOALS, ACTIONS.UPDATE), updateMetaValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const id = Number(req.params.id);

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

    const {
      tipo, valor_objetivo, id_categoria,
      fecha_inicio, fecha_fin, estado, progreso_actual,
    } = req.body;

    // ✅ Construir update dinámico (SIN id_usuario)
    const updates = {};
    if (tipo !== undefined) {
      const validTipos = ['diaria', 'semanal', 'mensual'];
      if (!validTipos.includes(tipo)) {
        return res.status(400).json({ error: 'Tipo inválido' });
      }
      updates.tipo = tipo;
    }
    if (estado !== undefined) {
      const validEstados = ['activa', 'completada', 'cancelada'];
      if (!validEstados.includes(estado)) {
        return res.status(400).json({ error: 'Estado inválido' });
      }
      updates.estado = estado;
    }
    if (valor_objetivo !== undefined) updates.valor_objetivo = valor_objetivo;
    if (id_categoria !== undefined) updates.id_categoria = id_categoria;
    if (fecha_inicio !== undefined) updates.fecha_inicio = fecha_inicio;
    if (fecha_fin !== undefined) updates.fecha_fin = fecha_fin;
    if (progreso_actual !== undefined) updates.progreso_actual = progreso_actual;

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

    // ✅ Validar id_categoria si se está actualizando
    if (id_categoria !== undefined && id_categoria !== null) {
      const [catExists] = await pool.query(
        'SELECT 1 FROM categorias WHERE id_categoria = ?',
        [id_categoria]
      );
      if (!catExists.length) {
        return res.status(400).json({ error: 'Categoría no existe' });
      }
    }

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

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

    if (result.affectedRows === 0) {
      return res.status(404).json({ error: 'Meta no encontrada o no autorizado' });
    }

    res.json({ ok: true, message: 'Meta actualizada' });
  } catch (e) {
    console.error('PUT /metas/:id error:', e);
    res.status(500).json({ error: 'Error al actualizar meta' });
  }
});

/**
 * ========================================
 * DELETE /api/metas/:id
 * ========================================
 * Elimina una meta del usuario autenticado
 *
 * CAMBIOS DE SEGURIDAD:
 * - ✅ Requiere autenticación
 * - ✅ Requiere permiso de DELETE en recurso GOALS
 * - ✅ Solo permite eliminar metas propias (ownership)
 */
router.delete('/:id', requireAuth, checkPermission(RESOURCES.GOALS, ACTIONS.DELETE), metaIdValidator, handleValidation, async (req, res) => {
  try {
    const { id_usuario } = req.user;
    const id = Number(req.params.id);

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

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

    if (result.affectedRows === 0) {
      return res.status(404).json({ error: 'Meta no encontrada o no autorizado' });
    }

    res.json({ ok: true, message: 'Meta eliminada' });
  } catch (e) {
    console.error('DELETE /metas/:id error:', e);
    res.status(500).json({ error: 'Error al eliminar meta' });
  }
});

module.exports = router;
