backend/src/controllers/diario.controller.js

/**
 * @file Controlador para las entradas del diario.
 * @description Gestiona las operaciones CRUD para las entradas del diario de los usuarios.
 * @requires ../models/diario_mongoose
 */
const Diario = require('../models/diario_mongoose');

/**
 * @function crearEntradaDiario
 * @description Crea una nueva entrada en el diario para el usuario autenticado.
 * @param {object} req - Objeto de petición de Express.
 * @param {object} res - Objeto de respuesta de Express.
 * @returns {Promise<void>}
 */
exports.crearEntradaDiario = async (req, res) => {
    try {
        const { titulo, cuerpo, password } = req.body;
        const usuarioId = req.user.id;

        // Validar campos requeridos
        if (!titulo || !cuerpo) {
            return res.status(400).json({ 
                message: 'Título y cuerpo son requeridos' 
            });
        }

        // Crear objeto de entrada
        const entradaData = {
            usuarioId,
            titulo,
            cuerpo
        };

        // Añadir password solo si se proporcionó
        if (password && password.trim() !== '') {
            entradaData.password = password;
        }

        const nuevaEntrada = new Diario(entradaData);
        await nuevaEntrada.save();

        // No devolver el password hasheado en la respuesta
        const entradaResponse = nuevaEntrada.toObject();
        delete entradaResponse.password;

        res.status(201).json({ 
            message: 'Entrada del diario creada con éxito', 
            entrada: entradaResponse 
        });
    } catch (error) {
        console.error('Error al crear entrada del diario:', error);
        res.status(500).json({ 
            message: 'Error al crear la entrada del diario', 
            error: error.message 
        });
    }
};

/**
 * @function obtenerEntradasDiario
 * @description Obtiene todas las entradas del diario del usuario autenticado.
 * @param {object} req - Objeto de petición de Express.
 * @param {object} res - Objeto de respuesta de Express.
 * @returns {Promise<void>}
 */
exports.obtenerEntradasDiario = async (req, res) => {
    try {
        const usuarioId = req.user.id;

        // Buscar entradas del usuario, ordenadas por fecha (más reciente primero)
        const entradas = await Diario.find({ usuarioId })
            .select('-password') // No devolver la contraseña hasheada
            .sort({ createdAt: -1 }); // Ordenar por fecha descendente

        res.status(200).json(entradas);
    } catch (error) {
        console.error('Error al obtener entradas del diario:', error);
        res.status(500).json({
            message: 'Error al obtener las entradas del diario',
            error: error.message
        });
    }
};

/**
 * @function obtenerEntradaDiarioPorId
 * @description Obtiene una entrada específica del diario por su ID.
 * @description Si el solicitante es el propietario, se le da acceso.
 * @description Si la entrada es pública (con contraseña), se verifica la contraseña.
 * @param {object} req - Objeto de petición de Express.
 * @param {object} res - Objeto de respuesta de Express.
 * @returns {Promise<void>}
 */
exports.obtenerEntradaDiarioPorId = async (req, res) => {
    try {
        const { id } = req.params;
        const { password } = req.body;
        const usuarioId = req.user ? req.user.id : null;

        const entrada = await Diario.findById(id);

        if (!entrada) {
            return res.status(404).json({ message: 'Entrada del diario no encontrada' });
        }

        // Si el usuario es el propietario, puede acceder
        if (entrada.usuarioId.toString() === usuarioId) {
            return res.status(200).json(entrada);
        }

        // Si la entrada no tiene contraseña, es privada para el autor
        if (!entrada.password) {
            return res.status(403).json({ message: 'Acceso denegado. Esta entrada es privada.' });
        }

        // Si la entrada tiene contraseña, verificarla
        if (!password) {
            return res.status(401).json({ message: 'Se requiere contraseña para acceder a esta entrada.' });
        }

        const passwordCorrecta = await entrada.compararPassword(password);
        if (passwordCorrecta) {
            const entradaPublica = entrada.toObject();
            delete entradaPublica.password; // No exponer el hash de la contraseña
            return res.status(200).json(entradaPublica);
        } else {
            return res.status(403).json({ message: 'Contraseña incorrecta.' });
        }

    } catch (error) {
        res.status(500).json({ message: 'Error al obtener la entrada del diario', error: error.message });
    }
};

/**
 * @function actualizarEntradaDiario
 * @description Actualiza una entrada del diario existente.
 * @param {object} req - Objeto de petición de Express.
 * @param {object} res - Objeto de respuesta de Express.
 * @returns {Promise<void>}
 */
exports.actualizarEntradaDiario = async (req, res) => {
    try {
        const { id } = req.params;
        const { titulo, cuerpo, password } = req.body;
        const usuarioId = req.user.id;

        const entrada = await Diario.findById(id);

        if (!entrada) {
            return res.status(404).json({ message: 'Entrada del diario no encontrada' });
        }

        if (entrada.usuarioId.toString() !== usuarioId) {
            return res.status(403).json({ message: 'No tienes permiso para actualizar esta entrada' });
        }

        if (titulo) entrada.titulo = titulo;
        if (cuerpo) entrada.cuerpo = cuerpo;
        if (password) {
            entrada.password = password;
        } else if (password === '') { // Permitir eliminar la contraseña
            entrada.password = undefined;
        }


        await entrada.save();
        res.status(200).json({ message: 'Entrada del diario actualizada con éxito', entrada });
    } catch (error) {
        res.status(500).json({ message: 'Error al actualizar la entrada del diario', error: error.message });
    }
};

/**
 * @function eliminarEntradaDiario
 * @description Elimina una entrada del diario.
 * @param {object} req - Objeto de petición de Express.
 * @param {object} res - Objeto de respuesta de Express.
 * @returns {Promise<void>}
 */
exports.eliminarEntradaDiario = async (req, res) => {
    try {
        const { id } = req.params;
        const usuarioId = req.user.id;

        const entrada = await Diario.findById(id);

        if (!entrada) {
            return res.status(404).json({ message: 'Entrada del diario no encontrada' });
        }

        if (entrada.usuarioId.toString() !== usuarioId) {
            return res.status(403).json({ message: 'No tienes permiso para eliminar esta entrada' });
        }

        await Diario.findByIdAndDelete(id);
        res.status(200).json({ message: 'Entrada del diario eliminada con éxito' });
    } catch (error) {
        res.status(500).json({ message: 'Error al eliminar la entrada del diario', error: error.message });
    }
};