#include "mainwindow.h"
#include "GestorDatos.h" // Para cargar/guardar datos
#include "EvaluacionesRamosWidget.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      miCalendario(new Calendario())
      // gestorDatos(new GestorDatos())
{
    // Cargar datos al iniciar la aplicación
    GestorDatos gestor; // Crear una instancia local de GestorDatos para la carga
    QList<Semestre*> semestresCargados;
    QList<Ramo*> ramosCargados;
    QList<ActividadAcademica*> eventosCargados; // ¡Ahora ActividadAcademica!
    QList<ActividadDiaria*> actividadesDiariasCargadas;

    Usuario* usuarioCargado = nullptr;

    //gestorDatos = new GestorDatos(); // ¡ELIMINADO! Ya se creó 'gestor' localmente

    // La llamada a cargarDatos ahora pasa la lista de ActividadAcademica*
    if (gestor.cargarDatos(usuarioCargado, semestresCargados, ramosCargados, eventosCargados, actividadesDiariasCargadas)) {
        miCalendario->setUsuario(usuarioCargado);
        miCalendario->setSemestres(semestresCargados);
        miCalendario->setRamos(ramosCargados);
        miCalendario->setEvents(eventosCargados); // ¡Ahora ActividadAcademica!
        miCalendario->setActividadesDiarias(actividadesDiariasCargadas);
        miCalendario->inicializarUsuario("Mi Usuario", "usuario@example.com", "Ingeniería");
        qDebug() << "Datos cargados exitosamente.";
    } else {
        qDebug() << "No se encontraron datos guardados o hubo un error al cargar. Inicializando datos por defecto.";
        miCalendario->inicializarUsuario("Mi Usuario", "usuario@example.com", "Ingeniería");
    }

    setupUi();
    connect(this, &MainWindow::dataChanged, this, &MainWindow::on_generarToDoButton_clicked);
    connect(this, &MainWindow::dataChanged, this, &MainWindow::on_refreshCalendarEvents);
    connect(this, &MainWindow::newData, this, &MainWindow::on_guardarDatosButton_clicked);
    connect(this, &MainWindow::dataChanged, this, &MainWindow::refreshEventosDisplay);

    refreshSemestresDisplay();
    refreshRamosDisplay();
    refreshEventosDisplay();
    on_generarToDoButton_clicked();
    emit dataChanged();
}

// Destructor
MainWindow::~MainWindow() {
    // Guardar datos al cerrar la aplicación
    GestorDatos gestor; // Crear una instancia local de GestorDatos para guardar
    if (miCalendario->getUsuario()) {
        gestor.guardarDatos(miCalendario->getUsuario(), miCalendario->getSemestres(),
                            miCalendario->getRamos(), miCalendario->getEvents(), // ¡Ahora ActividadAcademica!
                            miCalendario->getActividadesDiarias());
        qDebug() << "Datos guardados exitosamente al cerrar.";
    } else {
        qDebug() << "No hay usuario para guardar datos al cerrar.";
    }
    delete miCalendario;
    // delete gestorDatos; // ¡ELIMINADO! Ya no es un puntero miembro en MainWindow
}
void MainWindow::setupUi() {
    setWindowTitle("Planner Universitario");
    setMinimumSize(1000, 750);

    tabWidget = new QTabWidget(this);
    setCentralWidget(tabWidget);

    QWidget *semestresTab = new QWidget(tabWidget);
    QWidget *ramosTab = new QWidget(tabWidget);
    QWidget *eventosTab = new QWidget(tabWidget);
    QWidget *toDoTab = new QWidget(tabWidget);
    QWidget *dataControlTab = new QWidget(tabWidget);
    QWidget *calendarTab = new QWidget(tabWidget);

    setupSemestresTab(semestresTab);
    setupRamosTab(ramosTab);
    setupEventosTab(eventosTab);
    setupToDoTab(toDoTab);
    setupDataControlTab(dataControlTab);
    setupCalendarEventsTab(calendarTab);

    tabWidget->addTab(semestresTab, "Semestres");
    tabWidget->addTab(ramosTab, "Ramos");
    tabWidget->addTab(eventosTab, "Eventos");
    tabWidget->addTab(toDoTab, "To-Do Semanal");
    tabWidget->addTab(dataControlTab, "Datos");

    evaluacionesRamosWidget = new EvaluacionesRamosWidget(miCalendario, this);
    connect(evaluacionesRamosWidget, &EvaluacionesRamosWidget::evaluacionAgregada,
            this, &MainWindow::refreshEventosDisplay);

    connect(evaluacionesRamosWidget, &EvaluacionesRamosWidget::evaluacionAgregada,
            this, &MainWindow::on_refreshCalendarEvents);

    connect(evaluacionesRamosWidget, &EvaluacionesRamosWidget::evaluacionesActualizadas,
            this, &MainWindow::refreshEventosDisplay);

    connect(evaluacionesRamosWidget, &EvaluacionesRamosWidget::evaluacionesActualizadas,
            this, &MainWindow::on_refreshCalendarEvents);

    connect(evaluacionesRamosWidget, &EvaluacionesRamosWidget::evaluacionesActualizadas,
            this, &MainWindow::refreshRamosDisplay);



    tabWidget->addTab(evaluacionesRamosWidget, "Evaluaciones Ramos");
    //tabWidget->addTab(new EvaluacionesRamosWidget(miCalendario, this), "Evaluaciones Ramos"); // ¡Aquí estaba el widget!

    tabWidget->addTab(calendarTab, "Calendario de Eventos");
    connect(tabWidget, &QTabWidget::currentChanged, this, [this](int index){
        if (tabWidget->widget(index) == calendarEventsWidget) {
            qDebug() << "Refrescando pestaña de Calendario de Eventos.";
            calendarEventsWidget->refreshCalendarDisplay(); // Llama al método de refresco del widget
        }
    });
}

// --- Métodos para configurar las pestañas ---

void MainWindow::setupSemestresTab(QWidget* parentWidget) {
    QVBoxLayout *layout = new QVBoxLayout(parentWidget);

    agregarSemestreButton = new QPushButton("Agregar Nuevo Semestre", parentWidget);
    layout->addWidget(agregarSemestreButton);

    semestresDisplay = new QTextEdit("Semestres Registrados:", parentWidget);
    semestresDisplay->setReadOnly(true);
    layout->addWidget(semestresDisplay);

    connect(agregarSemestreButton, &QPushButton::clicked, this, &MainWindow::on_agregarSemestreButton_clicked);
}

void MainWindow::setupRamosTab(QWidget* parentWidget) {
    QVBoxLayout *layout = new QVBoxLayout(parentWidget);

    QHBoxLayout *buttonLayout = new QHBoxLayout();
    agregarRamoButton = new QPushButton("Agregar Nuevo Ramo", parentWidget);
    // Ya no necesitamos registrarNotaButton aquí si la funcionalidad está en EvaluacionesRamosWidget
    // Si queremos mantenerlo, es un camino alternativo. Por ahora, lo dejaré fuera para simplificar.
    registrarNotaButton = new QPushButton("Registrar Nota de Evaluación", parentWidget);

    buttonLayout->addWidget(agregarRamoButton);
    buttonLayout->addWidget(registrarNotaButton);
    buttonLayout->addStretch();
    layout->addLayout(buttonLayout);

    ramosDisplay = new QTextEdit("Ramos Inscritos:", parentWidget);
    ramosDisplay->setReadOnly(true);
    layout->addWidget(ramosDisplay);

    connect(agregarRamoButton, &QPushButton::clicked, this, &MainWindow::on_agregarRamoButton_clicked);
    connect(registrarNotaButton, &QPushButton::clicked, this, &MainWindow::on_registrarNotaButton_clicked);
}

void MainWindow::setupEventosTab(QWidget* parentWidget) {
    QVBoxLayout *layout = new QVBoxLayout(parentWidget);

    QHBoxLayout *buttonLayout = new QHBoxLayout();
    agregarTareaButton = new QPushButton("Agregar Tarea (con/sin Evaluación)", parentWidget);
    buttonLayout->addWidget(agregarTareaButton);
    buttonLayout->addStretch();
    layout->addLayout(buttonLayout);

    eventosDisplay = new QTextEdit("Eventos Académicos (Tareas, Proyectos, Certámenes):", parentWidget);
    eventosDisplay->setReadOnly(true);
    layout->addWidget(eventosDisplay);

    connect(agregarTareaButton, &QPushButton::clicked, this, &MainWindow::on_agregarTareaButton_clicked);
}

void MainWindow::setupToDoTab(QWidget* parentWidget) {
    QVBoxLayout *layout = new QVBoxLayout(parentWidget);

    QHBoxLayout *controlsLayout = new QHBoxLayout();
    controlsLayout->addWidget(new QLabel("Semana de Referencia:"));
    toDoDateEdit = new QDateEdit(QDate::currentDate(), parentWidget);
    toDoDateEdit->setCalendarPopup(true);
    toDoDateEdit->setDisplayFormat("dd/MM/yyyy");
    controlsLayout->addWidget(toDoDateEdit);

    generarToDoButton = new QPushButton("Generar To-Do Semanal", parentWidget);
    controlsLayout->addWidget(generarToDoButton);
    controlsLayout->addStretch();
    layout->addLayout(controlsLayout);

    // CÓDIGO ORIGINAL (reemplazado):
    // toDoDisplay = new QTextEdit("To-Do List Semanal (actividades sugeridas y entregas):", parentWidget);
    // toDoDisplay->setReadOnly(true);
    // layout->addWidget(toDoDisplay);

    toDoScrollArea = new QScrollArea(parentWidget); ///NUEVO
    toDoScrollContent = new QWidget(); ///NUEVO
    toDoLayout = new QVBoxLayout(toDoScrollContent); ///NUEVO
    toDoScrollArea->setWidget(toDoScrollContent); ///NUEVO
    toDoScrollArea->setWidgetResizable(true); ///NUEVO
    toDoScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); ///NUEVO
    toDoScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); ///NUEVO
    
    layout->addWidget(toDoScrollArea); ///NUEVO

    connect(generarToDoButton, &QPushButton::clicked, this, &MainWindow::on_generarToDoButton_clicked);
}


void MainWindow::setupDataControlTab(QWidget* parentWidget) {
    QVBoxLayout *layout = new QVBoxLayout(parentWidget);

    QHBoxLayout *buttonLayout = new QHBoxLayout();
    guardarDatosButton = new QPushButton("Guardar Datos Ahora", parentWidget);
    cargarDatosButton = new QPushButton("Cargar Datos del Archivo", parentWidget);
    eliminarDatosButton = new QPushButton("¡Eliminar Todos los Datos!", parentWidget);
    buttonLayout->addWidget(guardarDatosButton);
    buttonLayout->addWidget(cargarDatosButton);
    buttonLayout->addWidget(eliminarDatosButton);
    buttonLayout->addStretch();
    layout->addLayout(buttonLayout);

    layout->addStretch();

    connect(guardarDatosButton, &QPushButton::clicked, this, &MainWindow::on_guardarDatosButton_clicked);
    connect(cargarDatosButton, &QPushButton::clicked, this, &MainWindow::on_cargarDatosButton_clicked);
    connect(eliminarDatosButton, &QPushButton::clicked, this, &MainWindow::on_eliminarDatosButton_clicked);
}

void MainWindow::setupCalendarEventsTab(QWidget* parentWidget) {
    QVBoxLayout *layout = new QVBoxLayout(parentWidget);

    // Crear una instancia de tu CalendarViewWidget
    calendarEventsWidget = new CalendarViewWidget(parentWidget);
    layout->addWidget(calendarEventsWidget);

    // Si quisieras añadir un botón de "Recargar Eventos" específico para esta pestaña:
    /*
    QPushButton *reloadEventsButton = new QPushButton("Recargar Eventos del Archivo", parentWidget);
    layout->addWidget(reloadEventsButton);
    connect(reloadEventsButton, &QPushButton::clicked, calendarEventsWidget, &CalendarViewWidget::refreshCalendarDisplay);
    */
}




void MainWindow::on_agregarSemestreButton_clicked() {
    AddSemestreDialog dialog(this);
    if (dialog.exec() == QDialog::Accepted) {
        QString nombre = dialog.getNombre();
        QDate fechaInicio = dialog.getFechaInicio();
        QDate fechaFin = dialog.getFechaFin();
        emit dataChanged(); // Emitir la señal
        if (nombre.isEmpty() || !fechaInicio.isValid() || !fechaFin.isValid()) {
            QMessageBox::warning(this, "Datos Incompletos", "Por favor, complete todos los campos de semestre y asegúrese de que las fechas sean válidas.");
            return;
        }
        if (fechaInicio >= fechaFin) {
            QMessageBox::warning(this, "Fechas Inválidas", "La fecha de inicio debe ser anterior a la fecha de término.");
            return;
        }

        Semestre* nuevoSemestre = new Semestre(0, nombre, fechaInicio, fechaFin);
        miCalendario->agregarSemestre(nuevoSemestre);

        refreshSemestresDisplay();

        /* --- Uso de método para actualizar automáticamente la pestaña Evaluaciones Ramos --- */
        if (!evaluacionesRamosWidget) {
            qWarning() << "evaluacionesRamosWidget es nullptr!";
        } else {
            evaluacionesRamosWidget->recargarVista();
        }


        QMessageBox::information(this, "Semestre Agregado", "Se ha agregado el semestre: " + nombre);
        on_generarToDoButton_clicked();
        emit newData();
    } else {
        QMessageBox::information(this, "Acción Cancelada", "La adición del semestre ha sido cancelada.");
    }
}


// **MODIFICACIÓN CLAVE**: on_agregarRamoButton_clicked
void MainWindow::on_agregarRamoButton_clicked() {
    QList<Semestre*> semestresDisponibles = miCalendario->getSemestres();
    if (semestresDisponibles.isEmpty()) {
        QMessageBox::warning(this, "Error", "No hay semestres registrados. Primero debe agregar al menos un semestre para poder añadir un ramo.");
        return;
    }

    AddRamoDialog dialog(semestresDisponibles, this);
    if (dialog.exec() == QDialog::Accepted) {
        QString nombreRamo = dialog.getNombre();
        QString codigoRamo = dialog.getCodigo();
        int creditos = dialog.getCreditos();
        int semestreId = dialog.getSemestreIdSeleccionado();
        QString profesor = dialog.getProfesor();
        QColor color = dialog.getColor();
/*
        float totalHorasCatedra = dialog.getTotalHorasCatedra();
        float totalHorasAyudantiaPresencial = dialog.getTotalHorasAyudantiaPresencial();
        float totalHorasEvaluacionesPresencial = dialog.getTotalHorasEvaluacionesPresencial();
        float totalHorasOtrasPresencial = dialog.getTotalHorasOtrasPresencial();
        float totalHorasEstudioNoPresencial = dialog.getTotalHorasEstudioNoPresencial();
        float totalHorasProyectosNoPresencial = dialog.getTotalHorasProyectosNoPresencial();
*/
        // ¡IMPORTANTE! Las actividadesEvaluativas se obtienen primero del diálogo.
        // Pero aún no tienen el ramoAsociado asignado y no son parte de Calendario->eventos.
        QList<ActividadAcademica*> actividadesEvaluativasInfo = dialog.getActividadesEvaluativasDefinidas(nullptr); // Pasar nullptr temporalmente


        if (nombreRamo.isEmpty() || codigoRamo.isEmpty() || semestreId == 0) {
            QMessageBox::warning(this, "Datos Incompletos", "Por favor, complete al menos el nombre, código y seleccione un semestre.");
            // Si el diálogo no es aceptado, liberar las ActividadAcademica* creadas en el diálogo.
            for(ActividadAcademica* act : actividadesEvaluativasInfo) delete act;
            return;
        }

        Semestre* semestreAsociado = miCalendario->obtenerSemestrePorId(semestreId);
        if (!semestreAsociado) {
            QMessageBox::critical(this, "Error Lógico", "El semestre seleccionado no pudo ser encontrado. Esto es un error interno.");
            for(ActividadAcademica* act : actividadesEvaluativasInfo) delete act;
            return;
        }

        // 1. Crear el nuevo Ramo.
        Ramo* nuevoRamo = new Ramo(0, nombreRamo, codigoRamo, creditos, semestreAsociado, profesor, color);

        // 2. Agregar el nuevo Ramo al Calendario (es importante que el ramo exista antes de asociarle eventos).
        miCalendario->agregarRamo(nuevoRamo);

        // 3. Ahora, iterar sobre las actividades evaluativas obtenidas del diálogo:
        //    - Asignarles el 'nuevoRamo'.
        //    - Agregarlas a la lista global de eventos de 'miCalendario'.
        //    - Agregarlas a la lista de 'actividadesEvaluativas' del 'nuevoRamo'.
        for (ActividadAcademica* act : actividadesEvaluativasInfo) {
            if (act) {
                act->setRamoAsociado(nuevoRamo); // Asignar el ramo recién creado
                miCalendario->agregarEvento(act); // Añadir a la lista global de eventos
                nuevoRamo->agregarActividadEvaluativa(act); // Añadir a la lista local del ramo (referencia)
            }
        }
        // Nota: Ya no necesitamos delete act; aquí, porque miCalendario ahora es su dueño.


        refreshRamosDisplay();
        refreshEventosDisplay(); // También refrescar eventos para ver las nuevas actividades evaluativas
        QMessageBox::information(this, "Ramo Agregado", "Se ha agregado el ramo: " + nombreRamo);
        on_generarToDoButton_clicked();

        /* --- Uso de método para actualizar automáticamente la pestaña Evaluaciones Ramos --- */
        if (!evaluacionesRamosWidget) {
            qWarning() << "evaluacionesRamosWidget es nullptr!";
        } else {
            evaluacionesRamosWidget->recargarVista();
        }
        emit dataChanged();
        emit newData();
    } else {
        QMessageBox::information(this, "Acción Cancelada", "La adición del ramo ha sido cancelada.");
    }
}


void MainWindow::on_agregarTareaButton_clicked() {
    QList<Ramo*> ramosDisponibles = miCalendario->getRamos();
    if (ramosDisponibles.isEmpty()) {
        QMessageBox::warning(this, "Error", "No hay ramos registrados. Primero debe agregar al menos un ramo para poder añadir una tarea.");
        return;
    }

    AddTareaDialog dialog(ramosDisponibles, this);

    if (dialog.exec() == QDialog::Accepted) {
        emit dataChanged(); // Emitir la señal
        QString nombreTarea = dialog.getNombre();
        QString descripcionTarea = dialog.getDescripcion();
        QDate fechaInicio = dialog.getFechaInicio();
        QDate fechaFin = dialog.getFechaFin();
        int ramoId = dialog.getRamoIdSeleccionado();
        QDate fechaEntrega = dialog.getFechaEntrega();
        float estimacionHoras = dialog.getEstimacionHoras();

        bool esEvaluativa = dialog.esEvaluativa();
        QString nombreActividadEval = dialog.getNombreActividadEvaluativa();
        QString ponderacionActividadEvalString = dialog.getPonderacionActividadEvaluativaString();

        if (nombreTarea.isEmpty() || descripcionTarea.isEmpty() || ramoId == 0) {
            QMessageBox::warning(this, "Datos Incompletos", "Por favor, complete el nombre, descripción y seleccione un ramo.");
            return;
        }

        Ramo* ramoAsociado = miCalendario->obtenerRamoPorId(ramoId);
        if (!ramoAsociado) {
            QMessageBox::critical(this, "Error Lógico", "El ramo seleccionado no pudo ser encontrado. Esto es un error interno.");
            return;
        }

        // ActividadEvaluativa* actividadEval = nullptr; // ¡ActividadEvaluativa ya no existe!
        ActividadAcademica* actividadEval = nullptr; // ¡Ahora ActividadAcademica!
        if (esEvaluativa) {
            float ponderacionActividadEval = AddTareaDialog::evaluatePonderationExpression(ponderacionActividadEvalString);

            if (ponderacionActividadEval == 0.0f && ponderacionActividadEvalString != "0" && !ponderacionActividadEvalString.isEmpty()) {
                QMessageBox::critical(this, "Error de Ponderación", "La ponderación de la actividad evaluativa es inválida o cero después de evaluar. No se agregará la actividad evaluativa.");
                return;
            }

            QDate fechaCompleta = QDate(fechaEntrega);
            actividadEval = new ActividadAcademica(0, nombreActividadEval, "", fechaCompleta, fechaCompleta, ramoAsociado, ponderacionActividadEval, estimacionHoras, -1.0f);


           // actividadEval = new ActividadAcademica(0, nombreActividadEval, "", QDate(), QDate(), ramoAsociado, ponderacionActividadEval, -1.0f); // Usamos constructor base
            // Como Tarea va a heredar de ActividadAcademica, la creación directa de ActividadAcademica es incorrecta si es un evento.
            // Esto se corregirá más adelante si AddTareaDialog devuelve el tipo de actividad.
            // Por ahora, para que compile y refleje el cambio de clase, lo mantendré aquí.
            ramoAsociado->agregarActividadEvaluativa(actividadEval); // ¡ActividadAcademica!
        }

        // Tarea* nuevaTarea = new Tarea(0, nombreTarea, descripcionTarea, fechaInicio, fechaFin,
        //                               ramoAsociado, fechaEntrega,, estimacionHoras,
        //                               false, actividadEval); // <-- Constructor de Tarea necesita adaptarse a ActividadAcademica base

        // ¡CORRECCIÓN! El constructor de Tarea ya no toma el booleano 'completado' ni 'ActividadEvaluativa*'
        // sino que toma los atributos de ActividadAcademica base (ponderacion, notaObtenida)
        Tarea* nuevaTarea = new Tarea(0, nombreTarea, descripcionTarea, fechaInicio, fechaFin,
                                      ramoAsociado, estimacionHoras,
                                      (actividadEval ? actividadEval->getPonderacion() : 0.0f),
                                      (actividadEval ? actividadEval->getNotaObtenida() : -1.0f));


        miCalendario->agregarEvento(nuevaTarea); // ¡Ahora agrega ActividadAcademica*!

        refreshEventosDisplay();
        refreshRamosDisplay();
        QMessageBox::information(this, "Tarea Agregada", "Se ha agregado la tarea: " + nombreTarea);
        on_generarToDoButton_clicked();
        emit newData(); // Emitir la señal de datos nuevos
    } else {
        QMessageBox::information(this, "Acción Cancelada", "La adición de la tarea ha sido cancelada.");
    }
}

void MainWindow::on_registrarNotaButton_clicked() {
    if (miCalendario->getRamos().isEmpty()) {
        QMessageBox::warning(this, "Advertencia", "No hay ramos registrados para registrar notas.");
        return;
    }

    AddNotaDialog dialog(miCalendario, this);
    if (dialog.exec() == QDialog::Accepted) {
        Ramo* selectedRamo = dialog.getSelectedRamo();
        // ActividadEvaluativa* selectedActividad = dialog.getSelectedActividadEvaluativa(); // ¡ActividadEvaluativa ya no existe!
        ActividadAcademica* selectedActividad = dialog.getSelectedActividadEvaluativa(); // ¡Ahora ActividadAcademica!
        float nota = dialog.getNotaObtenida();
        bool completada = dialog.getEsCompletada();

        if (selectedRamo && selectedActividad) {
            selectedActividad->setNotaObtenida(nota);
            // El setCompletadaManual() es para forzar el estado, setNotaObtenida ya marca como completada si nota es válida.
            // Si la nota es -1.0f (N/R), entonces estaCompletada() será false a menos que se fuerce manualmente.
            selectedActividad->setCompletadaManual(completada);
            QMessageBox::information(this, "Nota Registrada",
                                     QString("Nota %.1f registrada para '%2' en el ramo '%3'.")
                                     .arg(nota)
                                     .arg(selectedActividad->getNombre()) // Usar getNombre()
                                     .arg(selectedRamo->getNombre()));
            refreshRamosDisplay();
            refreshEventosDisplay();
            GestorDatos gestor;
            gestor.guardarDatos(miCalendario->getUsuario(), miCalendario->getSemestres(),
                                miCalendario->getRamos(), miCalendario->getEvents(), // ¡Ahora ActividadAcademica!
                                miCalendario->getActividadesDiarias());
            on_generarToDoButton_clicked();
        } else {
            QMessageBox::warning(this, "Error", "No se seleccionó un ramo o actividad válida.");
        }
    } else {
        QMessageBox::information(this, "Acción Cancelada", "El registro de nota ha sido cancelado.");
    }
}


void MainWindow::on_guardarDatosButton_clicked() {
     GestorDatos gestor; // ¡ELIMINADO! gestorDatos ya es un miembro
    if (miCalendario->getUsuario()) {
        if (gestor.guardarDatos(miCalendario->getUsuario(), miCalendario->getSemestres(), // ¡Usar gestorDatos miembro!
                                miCalendario->getRamos(), miCalendario->getEvents(), // ¡Ahora ActividadAcademica!
                                 miCalendario->getActividadesDiarias())) {
            emit dataChanged(); // Emitir la señal
            QMessageBox::information(this, "Guardado Exitoso", "Todos los datos se han guardado correctamente.");
        } else {
            QMessageBox::critical(this, "Error de Guardado", "No se pudieron guardar los datos. Verifique los permisos de archivo.");
        }
    } else {
        QMessageBox::warning(this, "Advertencia", "No hay usuario inicializado para guardar datos.");
    }
}

void MainWindow::on_cargarDatosButton_clicked() {
    GestorDatos gestor; // ¡ELIMINADO! gestorDatos ya es un miembro
    miCalendario->clearAllData();

    Usuario* usuarioCargado = nullptr;
    QList<Semestre*> semestresCargados;
    QList<Ramo*> ramosCargados;
    QList<ActividadAcademica*> eventosCargados; // ¡Ahora ActividadAcademica!
    QList<ActividadDiaria*> actividadesDiariasCargadas;

    if (gestor.cargarDatos(usuarioCargado, semestresCargados, ramosCargados, eventosCargados,actividadesDiariasCargadas)) { // ¡Usar gestorDatos miembro!
        miCalendario->setUsuario(usuarioCargado);
        miCalendario->setSemestres(semestresCargados);
        miCalendario->setRamos(ramosCargados);
        miCalendario->setEvents(eventosCargados); // ¡Ahora ActividadAcademica!
        miCalendario->setActividadesDiarias(actividadesDiariasCargadas);
        emit dataChanged(); // Emitir la señal
        QMessageBox::information(this, "Carga Exitosa", "Los datos se han cargado correctamente.");
    } else {
        QMessageBox::warning(this, "Error de Carga", "No se pudieron cargar los datos o el archivo no existe. Se mantendrán los datos actuales o por defecto.");
        miCalendario->inicializarUsuario("Mi Usuario", "usuario@example.com", "Ingeniería");
    }
    refreshSemestresDisplay();
    refreshRamosDisplay();
    refreshEventosDisplay();
    on_generarToDoButton_clicked();
}


void MainWindow::on_eliminarDatosButton_clicked() {
    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(this, "Confirmar Eliminación",
                                  "¿Está seguro de que desea eliminar TODOS los datos (semestres, ramos, eventos, horarios)? Esta acción no se puede deshacer y borrará el archivo.",
                                  QMessageBox::Yes|QMessageBox::No);

    if (reply == QMessageBox::Yes) {
        miCalendario->clearAllData();
        ActividadAcademica::resetNextId();
        if (evaluacionesRamosWidget) {
            evaluacionesRamosWidget->limpiarVista();
        }
        GestorDatos gestor; // ¡ELIMINADO! gestorDatos ya es un miembro
        gestor.guardarDatos(miCalendario->getUsuario(), miCalendario->getSemestres(), // ¡Usar gestorDatos miembro!
                            miCalendario->getRamos(), miCalendario->getEvents(), // ¡Ahora ActividadAcademica!
                             miCalendario->getActividadesDiarias());
        refreshSemestresDisplay();
        refreshRamosDisplay();
        refreshEventosDisplay();
        on_generarToDoButton_clicked();

        evaluacionesRamosWidget->limpiarVista();


        emit dataChanged(); // Emitir la señal
        QMessageBox::information(this, "Datos Eliminados", "Todos los datos han sido eliminados y el archivo de datos ha sido reseteado.");
    } else {
        QMessageBox::information(this, "Acción Cancelada", "La eliminación de datos ha sido cancelada.");
    }
}



// MÉTODO MODIFICADO: La lógica básica era original, pero se adaptó para trabajar con checkboxes
void MainWindow::on_generarToDoButton_clicked() {
    if (miCalendario->getSemestres().isEmpty() && miCalendario->getRamos().isEmpty()) {
        // CÓDIGO ORIGINAL usaba QMessageBox y toDoDisplay->clear()
        // NUEVO CÓDIGO: Manejo directo del layout con mensajes estilizados
        
        // Limpiar el contenido anterior
        QLayoutItem* child; ///NUEVO
        while ((child = toDoLayout->takeAt(0)) != nullptr) { ///NUEVO
            if (child->widget()) { ///NUEVO
                delete child->widget(); ///NUEVO
            } ///NUEVO
            delete child; ///NUEVO
        } ///NUEVO
        
        QLabel* infoLabel = new QLabel("No hay semestres o ramos registrados para generar una To-Do List."); ///NUEVO
        infoLabel->setStyleSheet("color: black; font-weight: bold; margin: 20px;"); ///NUEVO
        toDoLayout->addWidget(infoLabel); ///NUEVO
        
        QLabel* helpLabel = new QLabel("Agregue semestres y ramos para generar una To-Do List semanal."); ///NUEVO
        helpLabel->setStyleSheet("color: black; margin: 10px 20px;"); ///NUEVO
        toDoLayout->addWidget(helpLabel); ///NUEVO
        
        toDoLayout->addStretch(); ///NUEVO
        return;
    }

    // CÓDIGO ORIGINAL: Estas líneas se mantuvieron igual
    QDate fechaSeleccionada = toDoDateEdit->date();
    QList<ActividadDiaria*> toDoList = miCalendario->generarToDoListSemanal(fechaSeleccionada);
    
    // CÓDIGO MODIFICADO: refreshToDoDisplay ahora crea checkboxes en lugar de texto
    refreshToDoDisplay(toDoList);
}

// NUEVO SLOT implementado para manejar checkboxes del To-Do ///NUEVO
// Este método no existía en el código original ///NUEVO
void MainWindow::on_actividadCompletada_toggled(bool checked) { ///NUEVO
    QCheckBox* checkbox = qobject_cast<QCheckBox*>(sender()); ///NUEVO
    if (!checkbox) { ///NUEVO
        qWarning() << "Error: No se pudo obtener el checkbox que envió la señal"; ///NUEVO
        return; ///NUEVO
    } ///NUEVO
    
    // Obtener la actividad asociada al checkbox ///NUEVO
    int actividadId = checkbox->property("actividadId").toInt(); ///NUEVO
    void* actividadPtr = checkbox->property("actividadPtr").value<void*>(); ///NUEVO
    ActividadDiaria* actividad = static_cast<ActividadDiaria*>(actividadPtr); ///NUEVO
    
    if (!actividad) {
        qWarning() << "Error: No se pudo obtener la actividad asociada al checkbox";
        return;
    }
    
    // Aquí puedes implementar la lógica para marcar la actividad como completada
    // Por ahora, solo mostraremos un mensaje de debug
    if (checked) {
        qDebug() << "Actividad marcada como completada:" << actividad->getNombre();
        
        // Si la actividad está relacionada con una tarea real (EventoAcademico), la marcamos como completada
        // Para esto necesitaríamos una conexión entre ActividadDiaria y EventoAcademico
        // Por ahora, buscaremos en los eventos si hay una tarea con el mismo nombre
        QList<ActividadAcademica*> eventos = miCalendario->getEvents();
        for (ActividadAcademica* evento : eventos) {
            if (evento && evento->getNombre() == actividad->getNombre() && !evento->estaCompletada()) {
                evento->setCompletadaManual(true);
                qDebug() << "Evento académico marcado como completado:" << evento->getNombre();
                
                // Refrescar las visualizaciones
                refreshEventosDisplay();
                
                // Guardar los datos
                GestorDatos gestor;
                gestor.guardarDatos(miCalendario->getUsuario(), miCalendario->getSemestres(),
                                    miCalendario->getRamos(), miCalendario->getEvents(),
                                     miCalendario->getActividadesDiarias());
                break;
            }
        }
        
        // Cambiar el estilo del texto para indicar que está completado
        QWidget* itemWidget = checkbox->parentWidget();
        if (itemWidget) {
            QLabel* textLabel = itemWidget->findChild<QLabel*>();
            if (textLabel) {
                textLabel->setStyleSheet("margin-left: 10px; color: black; text-decoration: line-through;");
            }
        }
        
    } else {
        qDebug() << "Actividad desmarcada:" << actividad->getNombre();
        
        // Buscar y desmarcar el evento académico correspondiente
        QList<ActividadAcademica*> eventos = miCalendario->getEvents();
        for (ActividadAcademica* evento : eventos) {
            if (evento && evento->getNombre() == actividad->getNombre() && evento->estaCompletada()) {
                evento->setCompletadaManual(false);
                qDebug() << "Evento académico desmarcado:" << evento->getNombre();
                
                // Refrescar las visualizaciones
                refreshEventosDisplay();
                
                // Guardar los datos
                GestorDatos gestor;
                gestor.guardarDatos(miCalendario->getUsuario(), miCalendario->getSemestres(),
                                    miCalendario->getRamos(), miCalendario->getEvents(),
                                     miCalendario->getActividadesDiarias());
                break;
            }
        }
        
        // Restaurar el estilo normal del texto
        QWidget* itemWidget = checkbox->parentWidget();
        if (itemWidget) {
            QLabel* textLabel = itemWidget->findChild<QLabel*>();
            if (textLabel) {
                textLabel->setStyleSheet("margin-left: 10px; color: black;");
            }
        }
    }
}

// Métodos de refresco de UI
void MainWindow::refreshSemestresDisplay() {
    semestresDisplay->clear();
    semestresDisplay->append("--- SEMESTRES REGISTRADOS ---");

    QList<Semestre*> listaDeSemestres = miCalendario->getSemestres();

    if (listaDeSemestres.isEmpty()) {
        semestresDisplay->append("No hay semestres registrados.");
        return;
    }
    for (Semestre* sem : listaDeSemestres) {
        if (!sem) {
            semestresDisplay->append("  [Semestre NULO DETECTADO - ERROR INTERNO]");
            continue;
        }
        semestresDisplay->append(QString("ID: %1 | Nombre: %2 | Inicio: %3 | Fin: %4 | Semanas: %5")
                                     .arg(sem->getIdSemestre())
                                     .arg(sem->getNombre())
                                     .arg(sem->getFechaInicio().toString("dd/MM/yyyy"))
                                     .arg(sem->getFechaFin().toString("dd/MM/yyyy"))
                                     .arg(sem->getNumeroSemanas()));
    }
}


// MÉTODO COMPLETAMENTE REESCRITO para usar checkboxes en lugar de QTextEdit ///NUEVO
// CÓDIGO ORIGINAL comentado al final del método ///NUEVO
void MainWindow::refreshToDoDisplay(const QList<ActividadDiaria*>& toDoList) { ///NUEVO
    // Limpiar el contenido anterior ///NUEVO
    QLayoutItem* child; ///NUEVO
    while ((child = toDoLayout->takeAt(0)) != nullptr) { ///NUEVO
        if (child->widget()) { ///NUEVO
            delete child->widget(); ///NUEVO
        } ///NUEVO
        delete child; ///NUEVO
    } ///NUEVO
    
    QDate fechaSeleccionada = toDoDateEdit->date();
    QDate semanaInicio = fechaSeleccionada.addDays(-(fechaSeleccionada.dayOfWeek() - 1)); // Lunes de la semana
    QDate semanaFin = semanaInicio.addDays(6); // Domingo de la semana

    // Título
    QLabel* titleLabel = new QLabel(QString("--- TO-DO LIST SEMANAL (%1 a %2) ---")
                                        .arg(semanaInicio.toString("dd/MM/yyyy"))
                                        .arg(semanaFin.toString("dd/MM/yyyy")));

    toDoLayout->addWidget(titleLabel);

    if (toDoList.isEmpty()) {
        QLabel* emptyLabel1 = new QLabel("No hay actividades programadas para esta semana.");
        QLabel* emptyLabel2 = new QLabel("Asegúrese de haber agregado ramos y configurado sus horas de dedicación, o de tener tareas/proyectos pendientes en el semestre activo.");
        toDoLayout->addWidget(emptyLabel1);
        toDoLayout->addWidget(emptyLabel2);
        toDoLayout->addStretch();
        return;
    }

    // Agrupar por día
    QMap<QDate, QList<ActividadDiaria*>> actividadesPorDia;
    for (ActividadDiaria* act : toDoList) {
        if (act) { // Comprobación de puntero nulo
            actividadesPorDia[act->getFecha()].append(act);
        }
    }

    // Iterar por día y crear checkboxes ///NUEVO
    QList<QDate> sortedDates = actividadesPorDia.keys(); ///NUEVO
    std::sort(sortedDates.begin(), sortedDates.end()); // Asegurar orden cronológico de los días ///NUEVO

    for (const QDate& date : sortedDates) { ///NUEVO
        // Separador de día ///NUEVO
        QLabel* dayLabel = new QLabel(QString("\n--- %1 (%2) ---") ///NUEVO
                                          .arg(date.toString("dd/MM/yyyy")) ///NUEVO
                                          .arg(date.toString("dddd"))); // Nombre del día de la semana ///NUEVO

        toDoLayout->addWidget(dayLabel); ///NUEVO

        for (ActividadDiaria* act : actividadesPorDia[date]) { ///NUEVO
            // Crear un layout horizontal para checkbox + texto ///NUEVO
            QHBoxLayout* itemLayout = new QHBoxLayout(); ///NUEVO
            
            // Crear el checkbox ///NUEVO
            QCheckBox* checkbox = new QCheckBox();
            
            // Verificar si la actividad ya está completada buscando en los eventos académicos
            bool isCompletado = false;
            QList<ActividadAcademica*> eventos = miCalendario->getEvents();
            for (ActividadAcademica* evento : eventos) {
                if (evento && evento->getNombre() == act->getNombre()) {
                    isCompletado = evento->estaCompletada();
                    break;
                }
            }
            
            checkbox->setChecked(isCompletado);
            
            // Almacenar la referencia a la actividad en el checkbox para poder identificarla después
            checkbox->setProperty("actividadId", act->getId());
            checkbox->setProperty("actividadPtr", QVariant::fromValue(static_cast<void*>(act)));
            
            // Crear el texto de la actividad
            QString ramoInfo = act->getRamoAsociado() ? (" (" + act->getRamoAsociado()->getNombre() + ")") : "";
            QString textoActividad = QString(" %1: %2 (%3 min) %4")
                                         .arg(act->getTipoString())
                                         .arg(act->getNombre())
                                         .arg(act->getDuracionMinutos())
                                         .arg(ramoInfo);
            
            QLabel* textLabel = new QLabel(textoActividad);
            
            // Aplicar estilo según el estado de completado
            if (isCompletado) {
            } else {
 
            }
            
            // Conectar el checkbox al slot ///NUEVO
            connect(checkbox, &QCheckBox::toggled, this, &MainWindow::on_actividadCompletada_toggled); ///NUEVO
            
            // Agregar al layout horizontal ///NUEVO
            itemLayout->addWidget(checkbox); ///NUEVO
            itemLayout->addWidget(textLabel); ///NUEVO
            itemLayout->addStretch(); // Para alinear a la izquierda ///NUEVO
            
            // Crear un widget contenedor para el layout horizontal ///NUEVO
            QWidget* itemWidget = new QWidget(); ///NUEVO
            itemWidget->setLayout(itemLayout); ///NUEVO

            
            // Agregar al layout principal ///NUEVO
            toDoLayout->addWidget(itemWidget); ///NUEVO
        }
    }
    
    // Agregar stretch al final para que los elementos se alineen arriba ///NUEVO
    toDoLayout->addStretch(); ///NUEVO
}

void MainWindow::refreshRamosDisplay() {
    ramosDisplay->clear();
    ramosDisplay->append("--- RAMOS INSCRITOS ---");
    QList<Ramo*> listaDeRamos = miCalendario->getRamos();
    if (listaDeRamos.isEmpty()) {
        ramosDisplay->append("No hay ramos registrados.");
        return;
    }
    for (Ramo* ramo : listaDeRamos) {
        if (!ramo) { ramosDisplay->append("  [Ramo NULO DETECTADO - ERROR INTERNO]"); continue; }

        QString semestreNombre = "N/A";
        if (ramo->getSemestreAsociado()) { semestreNombre = ramo->getSemestreAsociado()->getNombre(); }

        ramosDisplay->append(QString("ID: %1 | Nombre: %2 | Código: %3 | Créditos: %4 | Semestre: %5 | Profesor: %6 | Color: %7")
                             .arg(ramo->getIdRamo())
                             .arg(ramo->getNombre())
                             .arg(ramo->getCodigo())
                             .arg(ramo->getCreditos())
                             .arg(semestreNombre)
                             .arg(ramo->getProfesor())
                             .arg(ramo->getColorAsociado().name()));
        ramosDisplay->append("  > Horas de Dedicación (SCT-Chile):");


        QList<ActividadAcademica*> actividades = ramo->getActividadesEvaluativas();
        if (!actividades.isEmpty()) {
            ramosDisplay->append("  > Actividades Evaluativas:");
            for (ActividadAcademica* act : actividades) {
                if (!act) continue;
                ramosDisplay->append(QString("    - %1 (%2%) [Fecha: %3] [Est. Horas: %4 H] [Nota: %5] %6") // <-- Mostrar estimacionHoras
                                     .arg(act->getNombre())
                                     .arg(act->getPonderacion(), 0, 'f', 1)
                                     .arg(act->getFechaFin().toString("dd/MM/yyyy"))
                                     .arg(act->getEstimacionHoras(), 0, 'f', 1) // <-- Mostrar estimacionHoras
                                     .arg(act->getNotaObtenida() != -1.0f ? QString::number(act->getNotaObtenida(), 'f', 1) : "N/R")
                                     .arg(act->estaCompletada() ? "(Completada)" : "(Pendiente)"));
            }
            float notaFinal = ramo->calcularNotaFinal();
            ramosDisplay->append(QString("  > NOTA FINAL ESTIMADA: %1 (Avance: %2%)")
                                 .arg(notaFinal != 0.0f ? QString::number(notaFinal, 'f', 1) : "N/C (No computable)")
                                 .arg(QString::number(ramo->calcularAvance(), 'f', 1)));
        } else {
            ramosDisplay->append("  > No hay actividades evaluativas definidas para este ramo.");
        }
    }
}

void MainWindow::refreshEventosDisplay() {
    eventosDisplay->clear();
    eventosDisplay->append("--- TODAS LAS ACTIVIDADES ACADÉMICAS (EVENTOS) ---");

    // ¡CAMBIO AQUÍ! Ahora simplemente obtenemos la lista global de eventos
    // porque GestorDatos ya la habrá poblado con todas las actividades evaluativas
    // (y cualquier otro evento global que pudiera existir).
    QList<ActividadAcademica*> listaDeEventos = miCalendario->getEvents();

    // ... (el resto de la función refreshEventosDisplay permanece igual) ...
    // Ordenar y mostrar.
    std::sort(listaDeEventos.begin(), listaDeEventos.end(), [](const ActividadAcademica* a, const ActividadAcademica* b) {
        if (!a || !b) return false;
        return a->getFechaFin() < b->getFechaFin();
    });

    if (listaDeEventos.isEmpty()) {
        eventosDisplay->append("No hay actividades académicas (eventos o evaluaciones) registradas.");
        return;
    }

    for (ActividadAcademica* evento : listaDeEventos) {
        if (!evento) { eventosDisplay->append("  [Actividad NULA DETECTADA - ERROR INTERNO]"); continue; }

        QString ramoNombre = "N/A";
        QString semestreNombre = "N/A";
        if (evento->getRamoAsociado()) {
            ramoNombre = evento->getRamoAsociado()->getNombre();
            if (evento->getRamoAsociado()->getSemestreAsociado()) {
                semestreNombre = evento->getRamoAsociado()->getSemestreAsociado()->getNombre();
            }
        } else {
            qDebug() << "ADVERTENCIA: Actividad" << evento->getNombre() << "no tiene ramo asociado o es nulo.";
        }

        QString infoBasica = QString("ID: %1 | Tipo: %2 | Nombre: %3 | Ramo: %4 (Semestre: %5) | Fecha: %6 | Est. Horas: %7 H | Completado: %8")
                                 .arg(evento->getId())
                                 .arg(evento->obtenerTipoActividad())
                                 .arg(evento->getNombre())
                                 .arg(ramoNombre)
                                 .arg(semestreNombre)
                                 .arg(evento->getFechaFin().toString("dd/MM/yyyy"))
                                 .arg(evento->getEstimacionHoras(), 0, 'f', 1)
                                 .arg(evento->estaCompletada() ? "Sí" : "No");
        eventosDisplay->append(infoBasica);

        if (evento->getPonderacion() > 0) {
            eventosDisplay->append(QString("  > EVALUATIVA: Ponderación: %1% | Nota: %2")
                                       .arg(evento->getPonderacion(), 0, 'f', 1)
                                       .arg(evento->getNotaObtenida() != -1.0f ? QString::number(evento->getNotaObtenida(), 'f', 1) : "N/R"));
        }

        // Detalles específicos por tipo de actividad
        if (Tarea* tarea = dynamic_cast<Tarea*>(evento)) {
            QString semanaStr = "N/A";
            if (tarea->getRamoAsociado() && tarea->getRamoAsociado()->getSemestreAsociado()) {
                semanaStr = QString::number(tarea->getRamoAsociado()->getSemestreAsociado()->obtenerSemanaDesdeFecha(tarea->getFechaEntrega()));
            }
            eventosDisplay->append(QString("  -> ENTREGA TAREA: Fecha: %1 %2 (Semana %3)")
                                       .arg(tarea->getFechaEntrega().toString("dd/MM"))
                                       .arg(semanaStr)
                                       );
        } else if (Proyecto* proyecto = dynamic_cast<Proyecto*>(evento)) {
            QString semanaStr = "N/A";
            if (proyecto->getRamoAsociado() && proyecto->getRamoAsociado()->getSemestreAsociado()) {
                semanaStr = QString::number(proyecto->getRamoAsociado()->getSemestreAsociado()->obtenerSemanaDesdeFecha(proyecto->getFechaFin()));
            }
            eventosDisplay->append(QString("  -> PROYECTO: Fecha Límite: %1 (Semana %2) | Miembros: %3")
                                       .arg(proyecto->getFechaEntregaFinal().toString("dd/MM"))
                                       .arg(semanaStr)
                                       .arg(proyecto->getMiembrosEquipo().join(", ")));
            for (Hito* hito : proyecto->getHitos()) {
                if (!hito) { eventosDisplay->append("     [Hito NULO DETECTADO - ERROR INTERNO]"); continue; }
                eventosDisplay->append(QString("     Hito: %1 (%2) | Completado: %3")
                                           .arg(hito->getNombreHito())
                                           .arg(hito->getFechaHito().toString("dd/MM"))
                                           .arg(hito->isCompletado() ? "Sí" : "No"));
            }
        } else if (Certamen* certamen = dynamic_cast<Certamen*>(evento)) {
            QString semanaStr = "N/A";
            if (certamen->getRamoAsociado() && certamen->getRamoAsociado()->getSemestreAsociado()) {
                semanaStr = QString::number(certamen->getRamoAsociado()->getSemestreAsociado()->obtenerSemanaDesdeFecha(certamen->getFechaInicio()));
            }
            eventosDisplay->append(QString("  -> CERTAMEN: Sala: %1 | Tipo: %2 (Semana %3)")
                                       .arg(certamen->getSala())
                                       .arg(certamen->getTipoCertamen())
                                       .arg(semanaStr));
        } else {
            // Este es el caso de una ActividadAcademica genérica
            eventosDisplay->append(QString("  -> Actividad Genérica: Fecha Inicio: %1 | Fecha Fin: %2")
                                       .arg(evento->getFechaInicio().toString("dd/MM"))
                                       .arg(evento->getFechaFin().toString("dd/MM")));
        }
    }
}

void MainWindow::on_refreshCalendarEvents() {
    if (calendarEventsWidget) { // Make sure the widget exists
        qDebug() << "Calling refreshCalendarDisplay for CalendarEventsWidget.";

        GestorDatos gestor;
        gestor.guardarDatos(miCalendario->getUsuario(),
                            miCalendario->getSemestres(),
                            miCalendario->getRamos(),
                            miCalendario->getEvents(),
                            miCalendario->getActividadesDiarias());



        calendarEventsWidget->refreshCalendarDisplay();
    } else {
        qDebug() << "calendarEventsWidget is null, cannot refresh.";
    }
}
