#ifndef CALENDARIO_H
#define CALENDARIO_H

#include <QList>
#include <QDate>
#include <QDebug>
#include <QMap> // Para el registro de horas asignadas

#include "Usuario.h"
#include "Ramo.h"
#include "ActividadAcademica.h"
#include "Tarea.h"
#include "Proyecto.h"
#include "Certamen.h"
#include "Hito.h"
#include "Semestre.h"
#include "ActividadDiaria.h"
#include "GestorDatos.h" // Para el miembro gestorDatos

class Calendario {
public:
    Calendario();
    ~Calendario();

    void inicializarUsuario(const QString& nombre, const QString& email, const QString& carrera);
    Usuario* getUsuario() const;
    void setUsuario(Usuario* user);

    void agregarSemestre(Semestre* semestre);
    void eliminarSemestre(int idSemestre);
    Semestre* obtenerSemestrePorId(int idSemestre) const;
    QList<Semestre*> getSemestres() const;
    void setSemestres(const QList<Semestre*>& semestresList);

    void agregarRamo(Ramo* ramo);
    void eliminarRamo(int idRamo);
    Ramo* obtenerRamoPorId(int idRamo) const;
    QList<Ramo*> getRamos() const;
    void setRamos(const QList<Ramo*>& ramosList);

    void agregarEvento(ActividadAcademica* evento);
    void eliminarEvento(int idEvento);
    ActividadAcademica* obtenerEventoPorId(int idEvento) const;
    QList<ActividadAcademica*> getEvents() const;
    void setEvents(const QList<ActividadAcademica*>& eventosList);
    QList<ActividadAcademica*> obtenerEventosParaFecha(const QDate& fecha) const;
    QList<ActividadAcademica*> obtenerEventsPorRamo(int idRamo) const; // ¡Renombrado!
    QList<Tarea*> obtenerTareasPendientes() const; // Todavía devuelve Tarea*

    void agregarBloqueHorario(BloqueHorario* bloque);
    void eliminarBloqueHorario(int idBloque);
    BloqueHorario* obtenerBloqueHorarioPorId(int idBloque) const;
    QList<BloqueHorario*> getBloquesHorarios() const;
    void setBloquesHorarios(const QList<BloqueHorario*>& bloquesList);
    QList<BloqueHorario*> obtenerBloquesParaDia(Qt::DayOfWeek dia) const;
    bool verificarConflictosHorarios(BloqueHorario* nuevoBloque = nullptr) const;

    // Métodos de gestión de Actividades Diarias (para el To-Do List)
    void agregarActividadDiaria(ActividadDiaria* actividad);
    void eliminarActividadDiaria(int idActividad);
    ActividadDiaria* obtenerActividadDiariaPorId(int idActividad) const;
    QList<ActividadDiaria*> getActividadesDiarias() const;
    void setActividadesDiarias(const QList<ActividadDiaria*>& actividadesList);
    void clearAllData();
    QList<ActividadDiaria*> generarToDoListSemanal(const QDate& fechaReferencia) const;

private:
    Usuario* usuario;
    QList<Semestre*> semestres;
    QList<Ramo*> ramos;
    QList<ActividadAcademica*> eventos; // Lista global de ActividadAcademica
    QList<BloqueHorario*> bloquesHorarios;
    QList<ActividadDiaria*> actividadesDiarias; // Para actividades diarias guardadas por usuario

    GestorDatos gestorDatos; // GestorDatos es miembro de Calendario

    void clearRamos();
    void clearEvents(); // Renombrado de clearEventos a clearEvents para reflejar ActividadAcademica
    void clearBloquesHorarios();
    void clearSemestres();
    void clearActividadesDiarias();

    void resetAllNextIds();


    // --- Métodos Auxiliares para generarToDoListSemanal (REVISADOS) ---

    // Función para incluir recordatorios de entregas (tareas, proyectos, certámenes)
    void incorporarRecordatoriosDeEventos(QList<ActividadDiaria*>& toDoList, const QDate& semanaInicio, const QDate& semanaFin) const;
    void incorporarActividadesEvaluativasPendientes(QList<ActividadDiaria*>& toDoList, const QDate& semanaInicio, const QDate& semanaFin) const ;
    void distribuirHorasProyectos(QList<ActividadDiaria*>& toDoList, const QDate& semanaInicio, const QDate& semanaFin) const ;
    void distribuirHorasEstudio(QList<ActividadDiaria*>& toDoList, const QDate& semanaInicio, const QDate& semanaFin) const ;

    // Distribuye horas de avance para TAREAS Y PROYECTOS ESPECÍFICOS pendientes
    void distribuirHorasDeAvanceEnEventos(QList<ActividadDiaria*>& toDoList, const QDate& semanaInicio, const QDate& semanaFin) const;

    // Distribuye horas de estudio/proyecto para ESTUDIO Y PROYECTO GENERAL del ramo
    void distribuirHorasGeneralesDeRamo(QList<ActividadDiaria*>& toDoList, const QDate& semanaInicio, const QDate& semanaFin) const;

    // Helper: Carga máxima de horas SCT por crédito
    static constexpr float HORAS_SCT_POR_CREDITO = 1.5f; // Definición de la constante
    float getCargaMaximaSemanalRamo(const Ramo* ramo) const;
};

#endif // CALENDARIO_H
