#include "EvaluacionesRamosWidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QDateEdit> // Para QDateEdit
#include <QLineEdit> // Para QLineEdit
#include <QDoubleSpinBox> // Para QDoubleSpinBox (si se usa para notas)
#include <QDebug> // Para qDebug()
#include <QLabel>

// Helper para evaluar expresiones de ponderación (sin cambios)
float EvaluacionesRamosWidget::evaluateExpression(const QString& expression) {
    if (expression.isEmpty()) {
        return 0.0f;
    }

    bool ok;
    float value = expression.toFloat(&ok);
    if (ok) {
        return value;
    }

    if (expression.contains('/')) {
        QStringList parts = expression.split('/');
        if (parts.size() == 2) {
            float numerator = parts.at(0).trimmed().toFloat(&ok);
            if (!ok) {
                qWarning() << "Error de parsing: Numerador inválido en " << expression;
                return 0.0f;
            }
            float denominator = parts.at(1).trimmed().toFloat(&ok);
            if (!ok || denominator == 0.0f) {
                qWarning() << "Error de parsing: Denominador inválido o división por cero en " << expression;
                return 0.0f;
            }
            return numerator / denominator;
        }
    }
    qWarning() << "Error de parsing: Expresión no reconocida " << expression;
    return 0.0f;
}


// Constructor (ahora recibe Calendario*)
EvaluacionesRamosWidget::EvaluacionesRamosWidget(Calendario* calendario, QWidget *parent)
    : QWidget(parent), m_calendario(calendario), ramoActual(nullptr) {
    inicializarUI();
    cargarSemestres();
    connect(comboSemestres, &QComboBox::currentTextChanged, this, &EvaluacionesRamosWidget::cargarRamosDelSemestre);
    cargarRamosDelSemestre(); // Llamar inicialmente para cargar ramos del primer semestre
}

void EvaluacionesRamosWidget::inicializarUI() {
    comboSemestres = new QComboBox(this);
    listaRamos = new QListWidget(this);
    tablaEvaluaciones = new QTableWidget(this);
    botonGuardar = new QPushButton("Guardar Cambios", this);
    botonAgregar = new QPushButton("Agregar Evaluación", this);

    // Encabezados de la tabla: Nombre, Fecha, Nota, Ponderación
    QStringList headers = {"Nombre", "Fecha", "Completado", "Nota", "Ponderación (%)", "Estimación de Horas"};
    tablaEvaluaciones->setColumnCount(headers.size());
    tablaEvaluaciones->setHorizontalHeaderLabels(headers);
    tablaEvaluaciones->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // Ajustar columnas

    QHBoxLayout *topLayout = new QHBoxLayout;
    topLayout->addWidget(comboSemestres);
    topLayout->addWidget(listaRamos);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addLayout(topLayout);
    mainLayout->addWidget(tablaEvaluaciones);
    mainLayout->addWidget(botonGuardar);

    /* Botón para agregar evaluaciones */
    mainLayout->addWidget(botonAgregar);


            // Mensaje visual de "Cambios guardados"
        mensajeGuardadoLabel = new QLabel(this);
        mensajeGuardadoLabel->setStyleSheet("color: green; font-weight: bold;");
        mensajeGuardadoLabel->setAlignment(Qt::AlignCenter);
        mensajeGuardadoLabel->setVisible(false); // Oculto por defecto

        mensajeTimer = new QTimer(this);
        mensajeTimer->setSingleShot(true);
        connect(mensajeTimer, &QTimer::timeout, this, [this]() {
            mensajeGuardadoLabel->setVisible(false);
        });

        mainLayout->addWidget(mensajeGuardadoLabel);




    setLayout(mainLayout);

    connect(comboSemestres, &QComboBox::currentTextChanged, this, &EvaluacionesRamosWidget::cargarRamosDelSemestre);
    connect(listaRamos, &QListWidget::itemClicked, this, &EvaluacionesRamosWidget::mostrarEvaluaciones);
    connect(botonGuardar, &QPushButton::clicked, this, &EvaluacionesRamosWidget::guardarCambios);

    connect(botonAgregar, &QPushButton::clicked, this, [this]() {
        if (!ramoActual) {
            QMessageBox::warning(this, "Sin ramo seleccionado", "Selecciona un ramo antes de agregar evaluaciones.");
            return;
        }

        // Crear widgets para ingresar datos
        QDialog dialog(this);
        dialog.setWindowTitle("Agregar Evaluación");

        QVBoxLayout* layout = new QVBoxLayout(&dialog);

        QLineEdit* nombreEdit = new QLineEdit(&dialog);
        nombreEdit->setPlaceholderText("Nombre de la evaluación");

        QDateEdit* fechaEdit = new QDateEdit(QDate::currentDate(), &dialog);
        fechaEdit->setCalendarPopup(true);
        fechaEdit->setDisplayFormat("dd/MM/yyyy");

        QCheckBox* chekbox = new QCheckBox(&dialog);
        chekbox->setChecked(false);

        QDoubleSpinBox* notaSpin = new QDoubleSpinBox(&dialog);
        notaSpin->setRange(0.0, 100.0);
        notaSpin->setDecimals(1);
        notaSpin->setValue(0.0);
        notaSpin->setEnabled(false); // Inicialmente deshabilitado

        QLineEdit* ponderacionEdit = new QLineEdit(&dialog);
        ponderacionEdit->setPlaceholderText("Ponderación (porcentaje o fracción, ej: 20 o 55/2)");

        QLineEdit *estimacionHorasEdit = new QLineEdit(&dialog);
        estimacionHorasEdit->setPlaceholderText("Estimación de horas (ej: 10 o 40/3)");

        // Conectar el checkbox para habilitar/deshabilitar la nota
        connect(chekbox, &QCheckBox::toggled, notaSpin, &QDoubleSpinBox::setEnabled);
        layout->addWidget(nombreEdit);
        layout->addWidget(new QLabel("Fecha:"));
        layout->addWidget(fechaEdit);
        layout->addWidget(new QLabel("Completado:"));
        layout->addWidget(chekbox);
        layout->addWidget(new QLabel("Nota:"));
        layout->addWidget(notaSpin);
        layout->addWidget(new QLabel("Ponderación:"));
        layout->addWidget(ponderacionEdit);
        layout->addWidget(new QLabel("Estimación de horas:"));
        layout->addWidget(estimacionHorasEdit);


        QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
        layout->addWidget(buttons);

        connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
        connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);


        if (dialog.exec() == QDialog::Accepted) {
            QString nombre = nombreEdit->text().trimmed();
            QDate fecha = fechaEdit->date();
            float nota = chekbox->isChecked() ? static_cast<float>(notaSpin->value()) : 0.0; // Solo usar nota si está completado
            QString ponderacionStr = ponderacionEdit->text().trimmed();
            float ponderacion = evaluateExpression(ponderacionStr);
            float estimacionHoras = evaluateExpression(estimacionHorasEdit->text().trimmed());

            if (nombre.isEmpty() || ponderacionStr.isEmpty()) {
                QMessageBox::warning(this, "Campos vacíos", "Debes ingresar al menos el nombre y la ponderación.");
                return;
            }

            if (ponderacion == 0.0f && ponderacionStr != "0") {
                QMessageBox::warning(this, "Ponderación inválida", "La expresión de ponderación no es válida.");
                return;
            }

            // Crear evaluación

            QDate fechaHora = QDate(fecha); // Medianoche

            ActividadAcademica* nueva = new ActividadAcademica(
                0,
                nombre,
                "Agregada desde Evaluaciones", // descripción genérica
                fechaHora,
                fechaHora,
                ramoActual,
                ponderacion,
                nota,
                estimacionHoras, // Estimación de horas
                this
            );

            nueva->setCompletadaManual(chekbox->isChecked());

            ramoActual->agregarActividadEvaluativa(nueva);
            m_calendario->agregarEvento(nueva);

            // Recargar tabla
            mostrarEvaluaciones(new QListWidgetItem(ramoActual->getNombre()));
            emit evaluacionAgregada();

        }
    });

}

void EvaluacionesRamosWidget::cargarSemestres() {
    comboSemestres->clear();
    if (m_calendario && !m_calendario->getSemestres().isEmpty()) {
        for (Semestre* sem : m_calendario->getSemestres()) {
            if (sem) comboSemestres->addItem(sem->getNombre());
        }
        comboSemestres->setEnabled(true);
    } else {
        comboSemestres->addItem("No hay semestres disponibles");
        comboSemestres->setEnabled(false);
    }
}

void EvaluacionesRamosWidget::cargarRamosDelSemestre() {
    listaRamos->clear();
    mapaRamosVisibles.clear();

    tablaEvaluaciones->clearContents();
    tablaEvaluaciones->setRowCount(0);
    ramoActual = nullptr;

    QString nombreSemestreSeleccionado = comboSemestres->currentText();

    if (m_calendario && !m_calendario->getRamos().isEmpty()) {
        for (Ramo* ramo : m_calendario->getRamos()) {
            if (ramo && ramo->getSemestreAsociado() && ramo->getSemestreAsociado()->getNombre() == nombreSemestreSeleccionado) {
                QString nombre = ramo->getNombre();
                QListWidgetItem *item = new QListWidgetItem(nombre);
                listaRamos->addItem(item);
                mapaRamosVisibles[nombre] = ramo;
            }
        }
        listaRamos->setEnabled(true);
    } else {
        listaRamos->addItem("No hay ramos en este semestre.");
        listaRamos->setEnabled(false);
    }

}

void EvaluacionesRamosWidget::mostrarEvaluaciones(QListWidgetItem *item) {
    QString nombreRamoSeleccionado = item->text();
    if (!mapaRamosVisibles.contains(nombreRamoSeleccionado)) return;

    ramoActual = mapaRamosVisibles[nombreRamoSeleccionado];
    if (!ramoActual) return;

    QList<ActividadAcademica*> actividades = ramoActual->getActividadesEvaluativas();

    tablaEvaluaciones->setRowCount(actividades.size());
    actividadesEnTabla.clear(); // Limpiar el vector de mapeo de filas

    for (int i = 0; i < actividades.size(); ++i) {
        ActividadAcademica* act = actividades[i];
        if (!act) continue;

        actividadesEnTabla.append(act); // Guardar el puntero para recuperar en guardarCambios

        // Columna 0: Nombre (QLineEdit para edición)
        QLineEdit *nombreEdit = new QLineEdit(act->getNombre());
        tablaEvaluaciones->setCellWidget(i, 0, nombreEdit);

        // Columna 1: Fecha (QDateEdit para edición)
        // ¡CORRECCIÓN AQUÍ! Pasar QDate a QDateEdit
        QDateEdit *fechaEdit = new QDateEdit(act->getFechaFin(), this); // <--  para obtener QDate
        fechaEdit->setCalendarPopup(true);
        fechaEdit->setDisplayFormat("dd/MM/yyyy");
        tablaEvaluaciones->setCellWidget(i, 1, fechaEdit);

        // Columna 2: Completado (QCheckBox centrado en la celda)
        QWidget *completadoWidget = new QWidget(this);
        QCheckBox *completadoCheck = new QCheckBox(completadoWidget);
        completadoCheck->setChecked(act->estaCompletada());
        QHBoxLayout *completadoLayout = new QHBoxLayout(completadoWidget);
        completadoLayout->addWidget(completadoCheck, 0, Qt::AlignCenter);
        completadoLayout->setContentsMargins(0, 0, 0, 0);
        completadoWidget->setLayout(completadoLayout);
        tablaEvaluaciones->setCellWidget(i, 2, completadoWidget);

        // Columna 3: Nota (QDoubleSpinBox para edición)
        QDoubleSpinBox *notaSpin = new QDoubleSpinBox(this);
        notaSpin->setRange(0.0, 100.0); // Rango de notas de 0 a 100
        notaSpin->setSingleStep(0.1);
        notaSpin->setDecimals(1); // Mostrar un decimal
        notaSpin->setValue(act->tieneNota() ? act->getNotaObtenida() : 0.0);
        notaSpin->setEnabled(act->estaCompletada()); // Habilitar solo si está completada
        tablaEvaluaciones->setCellWidget(i, 3, notaSpin);

        // Conectar el checkbox para habilitar/deshabilitar la nota
        connect(completadoCheck, &QCheckBox::toggled, notaSpin, &QDoubleSpinBox::setEnabled);

        // Columna 3: Ponderación (QLineEdit para expresión)
        QLineEdit *ponderacionEdit = new QLineEdit(QString::number(act->getPonderacion(), 'f', 2));
        tablaEvaluaciones->setCellWidget(i, 4, ponderacionEdit);
        
        // colunmna 4: Estimación de horas (QLineEdit para expresión)
        QLineEdit *estimacionHorasEdit = new QLineEdit(QString::number(act->getEstimacionHoras(), 'f', 2));
        estimacionHorasEdit->setPlaceholderText("Ej: 10 o 40/3");
        tablaEvaluaciones->setCellWidget(i, 5, estimacionHorasEdit);

        // Opcional: Deshabilitar edición si no se quiere que el nombre o ponderación se cambien aquí
        // nombreEdit->setReadOnly(true);
        // ponderacionEdit->setReadOnly(true);
    }
}

void EvaluacionesRamosWidget::guardarCambios() {
    if (!ramoActual) {
        QMessageBox::warning(this, "Guardar Cambios", "No hay ramo seleccionado para guardar los cambios.");
        return;
    }

    // Validar si la suma de ponderaciones cambió (similar a AddRamoDialog)
    float totalPonderacionActual = 0.0f;
    for (int i = 0; i < tablaEvaluaciones->rowCount(); ++i) {
        QLineEdit *ponderacionEdit = qobject_cast<QLineEdit*>(tablaEvaluaciones->cellWidget(i, 3));
        if (ponderacionEdit) {
            float ponderacionValue = evaluateExpression(ponderacionEdit->text());
            if (ponderacionValue == 0.0f && !ponderacionEdit->text().trimmed().isEmpty() && ponderacionEdit->text().trimmed() != "0") {
                QMessageBox::warning(this, "Error de Ponderación",
                                     QString("La expresión de ponderación '%1' en la fila %2 no es válida.")
                                     .arg(ponderacionEdit->text()).arg(i + 1));
                return;
            }
            totalPonderacionActual += ponderacionValue;
        }
    }

    for (int i = 0; i < actividadesEnTabla.size(); ++i) {
        ActividadAcademica* act = actividadesEnTabla[i];
        if (!act) continue;

        QLineEdit* nombreEdit = qobject_cast<QLineEdit*>(tablaEvaluaciones->cellWidget(i, 0));
        QDateEdit* fechaEdit = qobject_cast<QDateEdit*>(tablaEvaluaciones->cellWidget(i, 1));
        
        // Obtener el checkbox del widget contenedor
        QWidget* completadoWidget = tablaEvaluaciones->cellWidget(i, 2);
        QCheckBox* completadoCheck = nullptr;
        if (completadoWidget) {
            completadoCheck = completadoWidget->findChild<QCheckBox*>();
        }
        
        QDoubleSpinBox* notaSpin = qobject_cast<QDoubleSpinBox*>(tablaEvaluaciones->cellWidget(i, 3));
        QLineEdit* ponderacionEdit = qobject_cast<QLineEdit*>(tablaEvaluaciones->cellWidget(i, 4));
        QLineEdit* estimacionHorasEdit = qobject_cast<QLineEdit*>(tablaEvaluaciones->cellWidget(i, 5)); 

        if (!nombreEdit || !fechaEdit || !completadoCheck || !notaSpin || !ponderacionEdit || !estimacionHorasEdit) {
            QMessageBox::critical(this, "Error de UI", "No se pudieron obtener todos los widgets de la fila " + QString::number(i));
            return;
        }

        act->setNombre(nombreEdit->text());
        // ¡CORRECCIÓN AQUÍ! Construir QDate desde QDate (fecha)
        act->setFechaFin(QDate(fechaEdit->date())); // <-- Constructor correcto

        // Solo actualizar la nota si el checkbox está marcado
        if (completadoCheck->isChecked()) {
            act->setNotaObtenida(static_cast<float>(notaSpin->value()));
        }
        
        act->setPonderacion(evaluateExpression(ponderacionEdit->text()));
        act->setEstimacionHoras(evaluateExpression(estimacionHorasEdit->text().trimmed())); 
        act->setCompletadaManual(completadoCheck->isChecked());
    }

    //QMessageBox::information(this, "Guardado", "Las evaluaciones fueron actualizadas correctamente."); // HAY QUE CAMBIAR ESTO
    emit evaluacionesActualizadas();

    mensajeGuardadoLabel->setText("Cambios guardados correctamente.");
    mensajeGuardadoLabel->setVisible(true);
    mensajeTimer->start(4000); // Ocultar mensaje después de 3 segundos


    if (m_calendario) {
        GestorDatos g;
        g.guardarDatos(m_calendario->getUsuario(),
                       m_calendario->getSemestres(),
                       m_calendario->getRamos(),
                       m_calendario->getEvents(),
                       m_calendario->getActividadesDiarias());
        //QMessageBox::information(this, "Guardado Completo", "Los cambios se guardaron permanentemente.");
    }

    

}


void EvaluacionesRamosWidget::recargarVista() {
    cargarSemestres();
    cargarRamosDelSemestre();
}

void EvaluacionesRamosWidget::limpiarVista() {
    comboSemestres->clear();
    comboSemestres->addItem("No hay semestres disponibles");
    comboSemestres->setEnabled(false);

    listaRamos->clear();
    listaRamos->addItem("No hay ramos en este semestre.");
    listaRamos->setEnabled(false);

    tablaEvaluaciones->clearContents();
    tablaEvaluaciones->setRowCount(0);

    ramoActual = nullptr;
    actividadesEnTabla.clear();
    mapaRamosVisibles.clear();
}


