frontend/src/pages/Diario.jsx

/**
 * @file Página del Diario.
 * @description Permite a los usuarios crear, ver, editar, eliminar y compartir entradas de su diario personal.
 * @requires react
 * @requires ../hooks
 * @requires ../service/diario.service
 * @requires ../components/molecules/DiaryEditor
 * @requires ../components/molecules/DiaryEntry
 * @requires ../components/atoms/Button
 * @requires ../components/atoms/Input
 * @requires ../styles/Diario.css
 */
import React, { useState, useEffect } from "react";
import { useToast } from "../hooks";
import { diarioService } from "../service/diario.service";
import DiaryEditor from "../components/molecules/DiaryEditor";
import DiaryEntry from "../components/molecules/DiaryEntry";
import Button from "../components/atoms/Button";
import Input from "../components/atoms/Input";
import "../styles/Diario.css";

/**
 * @function Diario
 * @description Componente principal de la página del diario. Gestiona el estado y la lógica para las entradas del diario.
 * @returns {JSX.Element} La página del diario.
 */
const Diario = () => {
    const { success: showSuccess, error: showError } = useToast();
    const [entries, setEntries] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [showEditor, setShowEditor] = useState(false);
    const [editingEntry, setEditingEntry] = useState(null);
    const [shareModal, setShareModal] = useState(null);

    // Cargar entradas al montar
    useEffect(() => {
        loadEntries();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    /**
     * @function loadEntries
     * @description Carga todas las entradas del diario del usuario desde el servicio.
     * @async
     */
    const loadEntries = async () => {
        setIsLoading(true);
        try {
            const data = await diarioService.getAll();
            setEntries(data);
        } catch (error) {
            showError(error.message || 'Error al cargar las entradas');
        } finally {
            setIsLoading(false);
        }
    };

    /**
     * @function handleCreateEntry
     * @description Maneja la creación de una nueva entrada del diario.
     * @param {object} entryData - Los datos de la nueva entrada.
     * @async
     */
    const handleCreateEntry = async (entryData) => {
        setIsLoading(true);
        try {
            const newEntry = await diarioService.create(entryData);
            showSuccess('¡Entrada creada exitosamente!');
            setEntries([newEntry.entrada, ...entries]);
            setShowEditor(false);
        } catch (error) {
            showError(error.message || 'Error al crear la entrada');
        } finally {
            setIsLoading(false);
        }
    };

    /**
     * @function handleUpdateEntry
     * @description Maneja la actualización de una entrada existente.
     * @param {object} entryData - Los nuevos datos para la entrada.
     * @async
     */
    const handleUpdateEntry = async (entryData) => {
        setIsLoading(true);
        try {
            const updated = await diarioService.update(editingEntry._id, entryData);
            showSuccess('¡Entrada actualizada exitosamente!');
            setEntries(entries.map(e => e._id === editingEntry._id ? updated.entrada : e));
            setShowEditor(false);
            setEditingEntry(null);
        } catch (error) {
            showError(error.message || 'Error al actualizar la entrada');
        } finally {
            setIsLoading(false);
        }
    };

    /**
     * @function handleDeleteEntry
     * @description Maneja la eliminación de una entrada.
     * @param {string} entryId - El ID de la entrada a eliminar.
     * @async
     */
    const handleDeleteEntry = async (entryId) => {
        if (!window.confirm('¿Estás seguro de que quieres eliminar esta entrada? Esta acción no se puede deshacer.')) {
            return;
        }

        setIsLoading(true);
        try {
            await diarioService.delete(entryId);
            showSuccess('Entrada eliminada exitosamente');
            setEntries(entries.filter(e => e._id !== entryId));
        } catch (error) {
            showError(error.message || 'Error al eliminar la entrada');
        } finally {
            setIsLoading(false);
        }
    };

    /**
     * @function handleEditEntry
     * @description Prepara el editor para modificar una entrada existente.
     * @param {object} entry - La entrada a editar.
     */
    const handleEditEntry = (entry) => {
        setEditingEntry(entry);
        setShowEditor(true);
    };

    /**
     * @function handleCancelEditor
     * @description Cancela la edición y cierra el editor.
     */
    const handleCancelEditor = () => {
        setShowEditor(false);
        setEditingEntry(null);
    };

    /**
     * @function handleShareEntry
     * @description Abre el modal para compartir una entrada.
     * @param {object} entry - La entrada a compartir.
     */
    const handleShareEntry = (entry) => {
        setShareModal(entry);
    };

    /**
     * @function copyShareLink
     * @description Copia el enlace para compartir al portapapeles.
     */
    const copyShareLink = () => {
        const url = `${window.location.origin}/diario/${shareModal._id}`;
        navigator.clipboard.writeText(url);
        showSuccess('¡Link copiado al portapapeles!');
    };

    /**
     * @function closeShareModal
     * @description Cierra el modal de compartir.
     */
    const closeShareModal = () => {
        setShareModal(null);
    };

    return (
        <div className="diario-page">
            <div className="diario-container">
                {!showEditor ? (
                    <>
                        {/* Header */}
                        <div className="diario-header">
                            <div className="diario-header__text">
                                <h1>Mi Diario Personal</h1>
                                <p>Un espacio privado para tus pensamientos, reflexiones y experiencias</p>
                            </div>
                            <Button
                                variant="primary"
                                onClick={() => setShowEditor(true)}
                                disabled={isLoading}
                            >
                                Nueva entrada
                            </Button>
                        </div>

                        {/* Lista de entradas */}
                        <div className="diario-content">
                            {isLoading && entries.length === 0 ? (
                                <div className="diario-loading">
                                    <div className="spinner"></div>
                                    <p>Cargando tus entradas...</p>
                                </div>
                            ) : entries.length === 0 ? (
                                <div className="diario-empty">
                                    <div className="diario-empty__icon">📝</div>
                                    <h2>Tu diario está vacío</h2>
                                    <p>Comienza a escribir tu primera entrada y lleva un registro de tus experiencias diarias</p>
                                    <Button
                                        variant="primary"
                                        onClick={() => setShowEditor(true)}
                                    >
                                        Crear primera entrada
                                    </Button>
                                </div>
                            ) : (
                                <div className="diario-entries">
                                    {entries.map(entry => (
                                        <DiaryEntry
                                            key={entry._id}
                                            entry={entry}
                                            onEdit={handleEditEntry}
                                            onDelete={handleDeleteEntry}
                                            onShare={handleShareEntry}
                                        />
                                    ))}
                                </div>
                            )}
                        </div>
                    </>
                ) : (
                    <DiaryEditor
                        onSave={editingEntry ? handleUpdateEntry : handleCreateEntry}
                        onCancel={handleCancelEditor}
                        initialData={editingEntry}
                        isLoading={isLoading}
                    />
                )}

                {/* Modal de compartir */}
                {shareModal && (
                    <div className="modal-overlay" onClick={closeShareModal}>
                        <div className="modal-content" onClick={(e) => e.stopPropagation()}>
                            <div className="modal-header">
                                <h2>🔗 Compartir entrada</h2>
                                <button className="modal-close" onClick={closeShareModal}>×</button>
                            </div>
                            <div className="modal-body">
                                <p className="modal-description">
                                    Comparte este link con quien quieras darle acceso a esta entrada.
                                    Necesitarán la contraseña que configuraste.
                                </p>
                                <div className="share-link-container">
                                    <Input
                                        value={`${window.location.origin}/diario/${shareModal._id}`}
                                        onChange={() => {}} // Read-only input
                                        icon="🔗"
                                    />
                                    <Button variant="primary" onClick={copyShareLink}>
                                        Copiar
                                    </Button>
                                </div>
                                <div className="share-info">
                                    <p>💡 <strong>Recuerda:</strong> La persona necesitará la contraseña que configuraste para acceder.</p>
                                </div>
                            </div>
                        </div>
                    </div>
                )}
            </div>
        </div>
    );
};

export default Diario;