<?php
	include_once APP_PATH . '/entities/EstadoAcademico.php';
	include_once APP_PATH . '/entities/Programa.php';
	include_once APP_PATH . '/entities/Curso.php';
	include_once APP_PATH . '/entities/Acuerdo.php';
	include_once APP_PATH . '/entities/Archivo.php';
	include_once APP_PATH . '/entities/Estudiante.php';
	include_once APP_PATH . '/entities/EstudianteCurso.php';
	include_once APP_PATH . '/entities/Usuario.php';

class ViewDataModelV1 {

    private $_db;
	public function __construct() {
		$this->_db = new Base;
	}

	public function send($data){

	}

    /**
     * Consulta dinámica principal que combina todos los filtros
     * @param array $filtros Array con los filtros aplicados
     * @return array Resultados de la consulta
     */


     private function buildBaseQuery($filtros, &$params) {
        $sql = "
             SELECT DISTINCT
                -- Datos principales del estudiante-curso
                ec.EstudianteCursoId,
                ec.Periodo,
                ec.Nota,
                ec.Observaciones,
                
                -- Información del estudiante
                e.CodigoEstudiante,
                e.Nombre as EstudianteNombre,
                
                -- Información del curso
                c.Codigo,
                c.Nombre as CursoNombre,
                
                -- Información del archivo
                a.ArchivoId,
                a.NombreArchivo,
                a.FechaSubida,
                
                -- Información del usuario que subió
                u.UsuarioId,
                u.Usuario,
                u.Nombre as UsuarioNombre,
                u.Apellidos as UsuarioApellidos,
                u.Correo,
                
                -- Información del programa académico
                p.ProgramaId,
                p.Nombre as ProgramaNombre,
                p.Codigo as ProgramaCodigo,
                
                -- Estado académico del estudiante
                ea.EstadoAcademicoId,
                ea.EstadoAcademico,
                ea.NombreEstado,
                
                -- Acuerdo académico
                ac.AcuerdoId,
                ac.NombreAcuerdo,
                
                -- Tipo de usuario
                tu.TipoUsuarioId,
                tu.NombreTipo
            FROM estudiantescursos ec
            INNER JOIN estudiantes e ON ec.CodigoEstudianteId = e.CodigoEstudiante
            INNER JOIN cursos c ON ec.CodigoCursoId = c.Codigo
            INNER JOIN archivos a ON ec.ArchivoId = a.ArchivoId
            INNER JOIN usuarios u ON a.UsuarioId = u.UsuarioId
            INNER JOIN tipos_usuario tu ON u.TipoUsuarioId = tu.TipoUsuarioId
            LEFT JOIN programas p ON e.ProgramaId = p.ProgramaId
            LEFT JOIN estados_academicos ea ON e.EstadoAcademicoId = ea.EstadoAcademicoId
            LEFT JOIN acuerdos ac ON e.AcuerdoId = ac.AcuerdoId
            WHERE 1=1
        ";

        $params = [];
        $conditions = [];

        $conditions = $this->buildFilterConditions($filtros, $params);

        if (!empty($conditions)) {
            $sql .= " AND " . implode(" AND ", $conditions);
        }

        return $sql;
    }

    public function contarResultados($filtros) {
        $params = [];
        $sqlBase = $this->buildBaseQuery($filtros, $params);
        $sqlCount = "SELECT COUNT(*) AS total FROM ($sqlBase) AS subconsulta";
        $this->_db->query($sqlCount, $params);
        return (int)$this->_db->rows_assoc()[0]['total'];
    }

    public function consultaDinamica($filtros, $pagina, $porPagina) {
       // 1. Contar registros totales con los mismos filtros
        $total = $this->contarResultados($filtros);

        // 2. Traer solo la página actual
        $params = [];
        $sqlBase = $this->buildBaseQuery($filtros, $params);
        $offset = ($pagina - 1) * $porPagina;
        $sqlDatos = $sqlBase . " ORDER BY a.FechaSubida DESC LIMIT $offset, $porPagina";

        $this->_db->query($sqlDatos, $params);
        $datos = $this->_db->rows_assoc();
        echo "<script>console.log('sqlDatos: " . json_encode($sqlDatos) . "');</script>";
        echo "<script>console.log('datos: " . json_encode($datos) . "');</script>";
        // 3. Retornar datos y total para que el controlador calcule páginas
        return [
            'datos' => $datos,
            'total' => $total
        ];
    }


     /*
    public function consultaDinamica($filtros) {
        // Construir la consulta base con todos los JOINs
        $sql = "
            SELECT DISTINCT
                -- Datos principales del estudiante-curso
                ec.EstudianteCursoId,
                ec.Periodo,
                ec.Nota,
                ec.Observaciones,
                
                -- Información del estudiante
                e.CodigoEstudiante,
                e.Nombre as EstudianteNombre,
                
                -- Información del curso
                c.Codigo,
                c.Nombre as CursoNombre,
                
                -- Información del archivo
                a.ArchivoId,
                a.NombreArchivo,
                a.FechaSubida,
                
                -- Información del usuario que subió
                u.UsuarioId,
                u.Usuario,
                u.Nombre as UsuarioNombre,
                u.Apellidos as UsuarioApellidos,
                u.Correo,
                
                -- Información del programa académico
                p.ProgramaId,
                p.Nombre as ProgramaNombre,
                p.Codigo as ProgramaCodigo,
                
                -- Estado académico del estudiante
                ea.EstadoAcademicoId,
                ea.EstadoAcademico,
                ea.NombreEstado,
                
                -- Acuerdo académico
                ac.AcuerdoId,
                ac.NombreAcuerdo,
                
                -- Tipo de usuario
                tu.TipoUsuarioId,
                tu.NombreTipo
            FROM estudiantescursos ec
            INNER JOIN estudiantes e ON ec.CodigoEstudianteId = e.CodigoEstudiante
            INNER JOIN cursos c ON ec.CodigoCursoId = c.Codigo
            INNER JOIN archivos a ON ec.ArchivoId = a.ArchivoId
            INNER JOIN usuarios u ON a.UsuarioId = u.UsuarioId
            INNER JOIN tipos_usuario tu ON u.TipoUsuarioId = tu.TipoUsuarioId
            LEFT JOIN programas p ON e.ProgramaId = p.ProgramaId
            LEFT JOIN estados_academicos ea ON e.EstadoAcademicoId = ea.EstadoAcademicoId
            LEFT JOIN acuerdos ac ON e.AcuerdoId = ac.AcuerdoId
            WHERE 1=1
        ";
        
        $params = [];
        $conditions = [];
        
        // FILTRO POR ESTUDIANTE
        if (isset($filtros['estudiante']) && !empty($filtros['estudiante'])) {
            $estudiantes = (array)$filtros['estudiante'];
            if (!in_array('0', $estudiantes)) { // Si no está "Todos" seleccionado
                $placeholders = str_repeat('?,', count($estudiantes) - 1) . '?';
                $conditions[] = "e.CodigoEstudiante IN ($placeholders)";
                $params = array_merge($params, $estudiantes);
            }
        }
        
        // FILTRO POR ESTADO ACADÉMICO - CORREGIDO
        if (isset($filtros['estado_academico']) && !empty($filtros['estado_academico'])) {
            $estados = (array)$filtros['estado_academico'];

            if (!in_array('0', $estados)) { // Si no está "Todos" seleccionado
                $placeholders = str_repeat('?,', count($estados) - 1) . '?';

                $conditions[] = "ea.EstadoAcademicoId IN ($placeholders)";  // Cambio: usar EstadoAcademico en lugar de EstadoAcademicoId
                $params = array_merge($params, $estados);
            }
        }
        
        // FILTRO POR PROGRAMA
        if (isset($filtros['programa']) && !empty($filtros['programa']) && $filtros['programa'] !== '0') {
            $conditions[] = "p.ProgramaId = ?";
            $params[] = $filtros['programa'];
        }
        
        // FILTRO POR CURSO
        if (isset($filtros['curso']) && !empty($filtros['curso']) && $filtros['curso'] !== '0') {
            $conditions[] = "c.Codigo = ?";
            $params[] = $filtros['curso'];
        }
        
        // FILTRO POR PERÍODO
        if (isset($filtros['periodo']) && !empty($filtros['periodo']) && $filtros['periodo'] !== '0') {
            $conditions[] = "ec.Periodo = ?";
            $params[] = $filtros['periodo'];
        }
        
        // FILTRO POR ACUERDO
        if (isset($filtros['acuerdo']) && !empty($filtros['acuerdo']) && $filtros['acuerdo'] !== '0') {
            $conditions[] = "ac.AcuerdoId = ?";
            $params[] = $filtros['acuerdo'];
        }
        
        // FILTRO POR ARCHIVO
        if (isset($filtros['archivo']) && !empty($filtros['archivo']) && $filtros['archivo'] !== '0') {
            $conditions[] = "a.ArchivoId = ?";
            $params[] = $filtros['archivo'];
        }
        
        // FILTRO POR FECHA DE SUBIDA   
        if (isset($filtros['fecha_subida_desde']) && !empty($filtros['fecha_subida_desde'])) {
            $conditions[] = "DATE(a.FechaSubida) >= ?";
            $params[] = $filtros['fecha_subida_desde'];
        }
        
        if (isset($filtros['fecha_subida_hasta']) && !empty($filtros['fecha_subida_hasta'])) {
            $conditions[] = "DATE(a.FechaSubida) <= ?";
            $params[] = $filtros['fecha_subida_hasta'];
        }
        
    
        // Agregar condiciones a la consulta
        if (!empty($conditions)) {
            $sql .= " AND " . implode(" AND ", $conditions);
        }
        
        // Ordenamiento
        $sql .= " ORDER BY e.CodigoEstudiante ASC, c.Nombre ASC, ec.Periodo ASC";
        
        
        // consulta para imprimir en consola
        $queryParaImprimir = $sql;
        foreach ($params as $valor) {
            $queryParaImprimir = preg_replace('/\?/', "'" . $valor . "'", $queryParaImprimir, 1);
        }
        echo "<script>console.log('" .  json_encode($queryParaImprimir) . "');</script>";   

        // EJECUTAR LA CONSULTA Y OBTENER RESULTADOS
        $this->_db->query($sql, $params);
        $resultados = $this->_db->rows_assoc(); 

        return $resultados;
    }
    */

    public function actualizarTodosFiltros($filtros) {
        $this->getEstadosAcademicosPorPeriodo($filtros['periodo']);
        $this->getEstudiantesPorFiltros($filtros['periodo'], $filtros['estado_academico'], $filtros['programa']);
        $this->getCursosPorFiltros($filtros['periodo'], $filtros['programa']);
    }

           /* 
     * Consulta para obtener promedio por periodo aplicando filtros
     */ 
     public function getPromedioPorPeriodo($filtros) {
        echo "<script>console.log('getPromedioPorPeriodo');</script>";
         $sql = "
             SELECT 
                 ec.Periodo,
                 ROUND(AVG(ec.Nota), 2) AS MediaNotas,
                 COUNT(ec.EstudianteCursoId) AS TotalRegistros
             FROM estudiantescursos ec
             INNER JOIN estudiantes e ON ec.CodigoEstudianteId = e.CodigoEstudiante
             INNER JOIN cursos c ON ec.CodigoCursoId = c.Codigo
             INNER JOIN archivos a ON ec.ArchivoId = a.ArchivoId
             LEFT JOIN programas p ON e.ProgramaId = p.ProgramaId
             LEFT JOIN estados_academicos ea ON e.EstadoAcademicoId = ea.EstadoAcademicoId
             LEFT JOIN acuerdos ac ON e.AcuerdoId = ac.AcuerdoId
             WHERE 1=1";

         $params = [];
         $conditions = [];
         
         $conditions = $this->buildFilterConditions($filtros, $params);
         
         if (!empty($conditions)) {
             $sql .= " AND " . implode(" AND ", $conditions);
         }

         $sql .= " GROUP BY ec.Periodo";
         $sql .= " ORDER BY ec.Periodo";

         // Para imprimir la consulta dinámica con los valores reemplazados:
         $consultaImprimible = $sql;
         foreach ($params as $valor) {
             // Escapar comillas simples en el valor para evitar errores en la impresión
             $valorSeguro = str_replace("'", "\\'", $valor);
             $consultaImprimible = preg_replace('/\?/', "'" . $valorSeguro . "'", $consultaImprimible, 1);
         }
         // Imprime la consulta en la consola del navegador para depuración
         echo "<script>console.log('Consulta dinámica: ' + " . json_encode($consultaImprimible) . ");</script>";

         $this->_db->query($sql, $params);
         
         $resultados = $this->_db->rows_assoc();
         
         // Convertir MediaNotas a número (float) en cada fila
         $resultados_final = [];
         foreach ($resultados as $fila) {
             if (isset($fila['MediaNotas'])) {
                 $fila['MediaNotas'] = floatval($fila['MediaNotas']);
                 $fila['TotalRegistros'] = intval($fila['TotalRegistros']);
                 $resultados_final[] = $fila;
             }
         }
         return $resultados_final;
     }

     /**
      * Consulta para obtener distribución de notas por estado académico
      */
     public function getDistribucionNotasPorEstado($filtros) {
         $sql = "
             SELECT 
                 ea.NombreEstado,
                 ROUND(AVG(ec.Nota), 2) AS MediaNotas,
                 COUNT(ec.EstudianteCursoId) AS TotalRegistros,
                 MIN(ec.Nota) AS NotaMinima,
                 MAX(ec.Nota) AS NotaMaxima
             FROM estudiantescursos ec
            INNER JOIN estudiantes e 
                ON ec.CodigoEstudianteId = e.CodigoEstudiante
            INNER JOIN cursos c 
                ON ec.CodigoCursoId = c.Codigo
            INNER JOIN archivos a 
                ON ec.ArchivoId = a.ArchivoId
            INNER JOIN usuarios u 
                ON a.UsuarioId = u.UsuarioId
            INNER JOIN tipos_usuario tu 
                ON u.TipoUsuarioId = tu.TipoUsuarioId
            LEFT JOIN programas p 
                ON e.ProgramaId = p.ProgramaId
            LEFT JOIN estados_academicos ea 
                ON e.EstadoAcademicoId = ea.EstadoAcademicoId
            LEFT JOIN acuerdos ac 
                ON e.AcuerdoId = ac.AcuerdoId
            WHERE 1=1";

         $params = [];
         $conditions = $this->buildFilterConditions($filtros, $params);
         
         if (!empty($conditions)) {
             $sql .= " AND " . implode(" AND ", $conditions);
         }

         $sql .= " GROUP BY ea.EstadoAcademicoId, ea.NombreEstado";
         $sql .= " ORDER BY MediaNotas DESC";
         // Para imprimir la consulta dinámica con los valores reemplazados:
         $consultaImprimible = $sql;
         foreach ($params as $valor) {
             // Escapar comillas simples en el valor para evitar errores en la impresión
             $valorSeguro = str_replace("'", "\\'", $valor);
             $consultaImprimible = preg_replace('/\?/', "'" . $valorSeguro . "'", $consultaImprimible, 1);
         }
         // Imprime la consulta en la consola del navegador para depuración
         echo "<script>console.log('Consulta dinámica: ' + " . json_encode($consultaImprimible) . ");</script>";

         $this->_db->query($sql, $params);
         $resultados = $this->_db->rows_assoc();
         $resultados_final = [];
         foreach ($resultados as $fila) {
             if (isset($fila['MediaNotas'])) {
                 $fila['MediaNotas'] = floatval($fila['MediaNotas']);
                 $fila['TotalRegistros'] = intval($fila['TotalRegistros']);
                 $fila['NotaMinima'] = floatval($fila['NotaMinima']);
                 $fila['NotaMaxima'] = floatval($fila['NotaMaxima']);
                 $resultados_final[] = $fila;
             }
         }
         return $resultados_final;
     }

     /**
      * Consulta para obtener rendimiento por materia/curso
      */
     public function getRendimientoPorMateria($filtros) {
         $sql = "
             SELECT 
                 c.Codigo as CursoCodigo,
                 c.Nombre as CursoNombre,
                 ROUND(AVG(ec.Nota), 2) AS MediaNotas,
                 COUNT(ec.EstudianteCursoId) AS TotalRegistros,
                 COUNT(DISTINCT e.CodigoEstudiante) AS TotalEstudiantes,
                 MIN(ec.Nota) AS NotaMinima,
                 MAX(ec.Nota) AS NotaMaxima,
                 ROUND(STDDEV(ec.Nota), 2) AS DesviacionEstandar,
                 COUNT(CASE WHEN ec.Nota >= 3.0 THEN 1 END) AS EstudiantesAprobados,
                 COUNT(CASE WHEN ec.Nota < 3.0 THEN 1 END) AS EstudiantesReprobados,
                 ROUND((COUNT(CASE WHEN ec.Nota >= 3.0 THEN 1 END) * 100.0 / COUNT(ec.EstudianteCursoId)), 2) AS PorcentajeAprobacion
             FROM estudiantescursos ec
             INNER JOIN estudiantes e ON ec.CodigoEstudianteId = e.CodigoEstudiante
             INNER JOIN cursos c ON ec.CodigoCursoId = c.Codigo
             INNER JOIN archivos a ON ec.ArchivoId = a.ArchivoId
             LEFT JOIN programas p ON e.ProgramaId = p.ProgramaId
             LEFT JOIN estados_academicos ea ON e.EstadoAcademicoId = ea.EstadoAcademicoId
             LEFT JOIN acuerdos ac ON e.AcuerdoId = ac.AcuerdoId
             WHERE 1=1";

         $params = [];
         $conditions = $this->buildFilterConditions($filtros, $params);
         
         if (!empty($conditions)) {
             $sql .= " AND " . implode(" AND ", $conditions);
         }

         $sql .= " GROUP BY c.Codigo, c.Nombre";
         $sql .= " ORDER BY MediaNotas DESC";

         // Debug: imprimir consulta
         $consultaImprimible = $sql;
         foreach ($params as $valor) {
             $valorSeguro = str_replace("'", "\\'", $valor);
             $consultaImprimible = preg_replace('/\?/', "'" . $valorSeguro . "'", $consultaImprimible, 1);
         }
         echo "<script>console.log('Consulta rendimiento por materia: ' + " . json_encode($consultaImprimible) . ");</script>";

         $this->_db->query($sql, $params);
         $resultados = $this->_db->rows_assoc();
         
         // Convertir tipos de datos
         $resultados_final = [];
         foreach ($resultados as $fila) {
             $fila['MediaNotas'] = floatval($fila['MediaNotas']);
             $fila['TotalRegistros'] = intval($fila['TotalRegistros']);
             $fila['TotalEstudiantes'] = intval($fila['TotalEstudiantes']);
             $fila['NotaMinima'] = floatval($fila['NotaMinima']);
             $fila['NotaMaxima'] = floatval($fila['NotaMaxima']);
             $fila['DesviacionEstandar'] = floatval($fila['DesviacionEstandar']);
             $fila['EstudiantesAprobados'] = intval($fila['EstudiantesAprobados']);
             $fila['EstudiantesReprobados'] = intval($fila['EstudiantesReprobados']);
             $fila['PorcentajeAprobacion'] = floatval($fila['PorcentajeAprobacion']);
             $resultados_final[] = $fila;
         }
         
         return $resultados_final;
     }

     /* Mejores promedios por periodo */
	/* Top 5 estudiantes con mejor rendimiento */
	public function getTop5EstudiantesRendimiento($filtros) {
		$sql = "SELECT 
			e.CodigoEstudiante,
			e.Nombre AS NombreEstudiante,
			p.Nombre AS ProgramaNombre,
			ec.Periodo,
			COUNT(DISTINCT ec.CodigoCursoId) AS TotalMaterias,
			ROUND(AVG(ec.Nota), 2) AS PromedioNotas
		FROM estudiantescursos ec
		INNER JOIN estudiantes e 
			ON ec.CodigoEstudianteId = e.CodigoEstudiante
		INNER JOIN cursos c 
			ON ec.CodigoCursoId = c.Codigo
		INNER JOIN archivos a 
			ON ec.ArchivoId = a.ArchivoId
		INNER JOIN usuarios u 
			ON a.UsuarioId = u.UsuarioId
		INNER JOIN tipos_usuario tu 
			ON u.TipoUsuarioId = tu.TipoUsuarioId
		LEFT JOIN programas p 
			ON e.ProgramaId = p.ProgramaId
		LEFT JOIN estados_academicos ea 
			ON e.EstadoAcademicoId = ea.EstadoAcademicoId
		LEFT JOIN acuerdos ac 
			ON e.AcuerdoId = ac.AcuerdoId
		WHERE 1=1";
        $params = [];
        $conditions = $this->buildFilterConditions($filtros, $params);
        if (!empty($conditions)) {
            $sql .= " AND " . implode(" AND ", $conditions);
        }
        $sql .= " GROUP BY e.CodigoEstudiante, e.Nombre, p.Nombre, ec.Periodo";
        $sql .= " HAVING COUNT(DISTINCT ec.CodigoCursoId) >= 5";
        $sql .= " ORDER BY PromedioNotas DESC, TotalMaterias DESC";
        $sql .= " LIMIT 5";
        // Debug: imprimir consulta
        echo "<script>console.log('Consulta Top 5 Estudiantes Rendimiento: ' + " . json_encode($sql) . ");</script>";
        $consultaImprimible = $sql;
        foreach ($params as $valor) {
            $valorSeguro = str_replace("'", "\\'", $valor);
            $consultaImprimible = preg_replace('/\?/', "'" . $valorSeguro . "'", $consultaImprimible, 1);
        }
        echo "<script>console.log('Consulta Top 5 Estudiantes Rendimiento: ' + " . json_encode($consultaImprimible) . ");</script>";

        $this->_db->query($sql, $params);
        return $this->_db->rows_assoc();
    }

	/**
	 * Obtiene el Top 5 de estudiantes con peor rendimiento académico.
	 */
	public function getTop5EstudiantesPeorRendimiento($filtros) {
		$sql = "SELECT 
			e.CodigoEstudiante,
			e.Nombre AS NombreEstudiante,
			p.Nombre AS ProgramaNombre,
			ec.Periodo,
			COUNT(DISTINCT ec.CodigoCursoId) AS TotalMaterias,
			ROUND(AVG(ec.Nota), 2) AS PromedioNotas
		FROM estudiantescursos ec
		INNER JOIN estudiantes e 
			ON ec.CodigoEstudianteId = e.CodigoEstudiante
		INNER JOIN cursos c 
			ON ec.CodigoCursoId = c.Codigo
		INNER JOIN archivos a 
			ON ec.ArchivoId = a.ArchivoId
		INNER JOIN usuarios u 
			ON a.UsuarioId = u.UsuarioId
		INNER JOIN tipos_usuario tu 
			ON u.TipoUsuarioId = tu.TipoUsuarioId
		LEFT JOIN programas p 
			ON e.ProgramaId = p.ProgramaId
		LEFT JOIN estados_academicos ea 
			ON e.EstadoAcademicoId = ea.EstadoAcademicoId
		LEFT JOIN acuerdos ac 
			ON e.AcuerdoId = ac.AcuerdoId
		WHERE 1=1";
		$params = [];
		$conditions = $this->buildFilterConditions($filtros, $params);
		if (!empty($conditions)) {
			$sql .= " AND " . implode(" AND ", $conditions);
		}
		$sql .= " GROUP BY e.CodigoEstudiante, e.Nombre, p.Nombre, ec.Periodo";
		$sql .= " HAVING COUNT(DISTINCT ec.CodigoCursoId) >= 5";
		$sql .= " ORDER BY PromedioNotas ASC, TotalMaterias ASC";
		$sql .= " LIMIT 5";
		// Debug: imprimir consulta
		echo "<script>console.log('Consulta Top 5 Estudiantes Peor Rendimiento: ' + " . json_encode($sql) . ");</script>";
		$consultaImprimible = $sql;
		foreach ($params as $valor) {
			$valorSeguro = str_replace("'", "\\'", $valor);
			$consultaImprimible = preg_replace('/\?/', "'" . $valorSeguro . "'", $consultaImprimible, 1);
		}
		echo "<script>console.log('Consulta Top 5 Estudiantes Peor Rendimiento: ' + " . json_encode($consultaImprimible) . ");</script>";
		$this->_db->query($sql, $params);
		return $this->_db->rows_assoc();
	}


    
     /**
      * Método auxiliar para construir condiciones de filtro (evita duplicación de código)
      */
      private function buildFilterConditions($filtros, &$params) {
        $conditions = [];
        
        // FILTRO POR ESTUDIANTE
        if (isset($filtros['estudiante']) && !empty($filtros['estudiante'])) {
            $estudiantes = (array)$filtros['estudiante'];
            if (!in_array('0', $estudiantes)) {
                $placeholders = str_repeat('?,', count($estudiantes) - 1) . '?';
                $conditions[] = "e.CodigoEstudiante IN ($placeholders)";
                $params = array_merge($params, $estudiantes);
            }
        }
        
        // FILTRO POR ESTADO ACADÉMICO
        if (isset($filtros['estado_academico']) && !empty($filtros['estado_academico'])) {
            $estados = (array)$filtros['estado_academico'];
            if (!in_array('0', $estados)) {
                $placeholders = str_repeat('?,', count($estados) - 1) . '?';
                $conditions[] = "ea.EstadoAcademicoId IN ($placeholders)";
                $params = array_merge($params, $estados);
            }
        }
        
        // FILTRO POR PROYECTO CURRICULAR
        if (isset($filtros['proyecto_curricular']) && !empty($filtros['proyecto_curricular'])) {
            $conditions[] = "p.ProgramaId = ?";
            $params[] = $filtros['proyecto_curricular'];
        }

        // FILTRO POR ESPACIO ACADÉMICO
        if (isset($filtros['espacio_academico']) && !empty($filtros['espacio_academico'])) {
            $conditions[] = "c.Codigo = ?";
            $params[] = $filtros['espacio_academico'];
        }

        // FILTRO POR PROGRAMA
        if (isset($filtros['programa']) && !empty($filtros['programa']) && $filtros['programa'] !== '0') {
            $conditions[] = "p.ProgramaId = ?";
            $params[] = $filtros['programa'];
        }
        
        // FILTRO POR CURSO
        if (isset($filtros['curso']) && !empty($filtros['curso']) && $filtros['curso'] !== '0') {
            $conditions[] = "c.Codigo = ?";
            $params[] = $filtros['curso'];
        }
        
        // FILTRO POR PERÍODO
        // Validar si el filtro de periodo es un array que contiene solo "0"
        if (isset($filtros['periodo']) && !empty($filtros['periodo'])) {
            $periodos = $filtros['periodo'];
            if (is_array($periodos)) {
                // Si el array contiene solo "0", no aplicar filtro
                if (count($periodos) === 1 && ($periodos[0] === '0' || $periodos[0] === 0)) {
                    // No agregar condición
                } else {
                    // Si es array y no es solo "0", usar IN
                    $placeholders = str_repeat('?,', count($periodos) - 1) . '?';
                    $conditions[] = "ec.Periodo IN ($placeholders)";
                    $params = array_merge($params, $periodos);
                }
            } else {
                // Si es string y no es "0", solo un período
                if ($periodos !== '0') {
                    $conditions[] = "ec.Periodo = ?";
                    $params[] = $periodos;
                }
            }
        }
		
        
        // FILTRO POR ACUERDO
        if (isset($filtros['acuerdo']) && !empty($filtros['acuerdo']) && $filtros['acuerdo'] !== '0') {
            $conditions[] = "ac.AcuerdoId = ?";
            $params[] = $filtros['acuerdo'];
        }
        
        // FILTRO POR ARCHIVO
        if (isset($filtros['archivo']) && !empty($filtros['archivo']) && $filtros['archivo'] !== '0') {
            $conditions[] = "a.ArchivoId = ?";
            $params[] = $filtros['archivo'];
        }
        
        // FILTRO POR FECHA DE SUBIDA
        if (isset($filtros['fecha_subida_desde']) && !empty($filtros['fecha_subida_desde'])) {
            $conditions[] = "DATE(a.FechaSubida) >= ?";
            $params[] = $filtros['fecha_subida_desde'];
        }
        
        if (isset($filtros['fecha_subida_hasta']) && !empty($filtros['fecha_subida_hasta'])) {
            $conditions[] = "DATE(a.FechaSubida) <= ?";
            $params[] = $filtros['fecha_subida_hasta'];
        }

        return $conditions;
    }
    
    /**
     * @return Acuerdo[]
    */
    public function getAcuerdos() {
		$this->_db->query('SELECT AcuerdoId, NombreAcuerdo FROM acuerdos');
		$resultados = $this->_db->rows_assoc();
		$acuerdos = [];
		foreach ($resultados as $row) {
			$acuerdos[] = new Acuerdo($row['AcuerdoId'], $row['NombreAcuerdo']);
		}
		return $acuerdos;
	}
    /**
     * @return Archivo[]
    */
    public function getArchivos() {
        $this->_db->query('SELECT ArchivoId, NombreArchivo, FechaSubida, UsuarioId FROM archivos');
        $resultados = $this->_db->rows_assoc();
        $archivos = [];
        foreach ($resultados as $row) {
            $archivos[] = new Archivo($row['ArchivoId'], $row['NombreArchivo'], $row['FechaSubida'], $row['UsuarioId']);
        }
        return $archivos;
    }
    /**
     * @return Curso[]
    */
    public function getCursos() {
        $this->_db->query('SELECT Codigo, Nombre FROM cursos');
        $resultados = $this->_db->rows_assoc();
        $cursos = [];
        foreach ($resultados as $row) {
            $cursos[] = new Curso($row['Codigo'], $row['Nombre']);
        }
        return $cursos;
    }

    /**
     * @return EstadoAcademico[]
    */
    public function getEstadosAcademicos() {
        // Consulta real a la tabla estados_academicos
        $this->_db->query('SELECT EstadoAcademicoId, EstadoAcademico, NombreEstado FROM estados_academicos');
        $resultados = $this->_db->rows_assoc();
        $estados = [];
        foreach ($resultados as $row) {
            $estados[] = new EstadoAcademico(
                $row['EstadoAcademicoId'],
                $row['EstadoAcademico'],
                $row['NombreEstado']
            );
        }
        return $estados;
    }

    /**
     * @return Estudiante[]
    */
    public function getEstudiantes() {
        $this->_db->query('SELECT CodigoEstudiante, Nombre, EstadoAcademicoId, ProgramaId, AcuerdoId FROM estudiantes');
        $resultados = $this->_db->rows_assoc();
        $estudiantes = [];
        foreach ($resultados as $row) {
            $estudiantes[] = new Estudiante(
                $row['CodigoEstudiante'], 
                $row['Nombre'],
                $row['EstadoAcademicoId'],
                $row['ProgramaId'],
                $row['AcuerdoId']
            );
        }
        return $estudiantes;
    }

	public function getProgramas() {
		$this->_db->query('SELECT ProgramaId, Nombre, Codigo FROM programas');
		$resultados = $this->_db->rows_assoc();
		$programas = [];
		foreach ($resultados as $row) {
			$programas[] = new Programa($row['ProgramaId'], $row['Nombre'], $row['Codigo']);
		}
		return $programas;
	}

    /**
     * Obtiene los periodos de los estudiantescursos
     * @return string[]
    */
    public function getPeriodos() {
        $this->_db->query('SELECT distinct Periodo FROM estudiantescursos');
        $resultados = $this->_db->rows_assoc();
        $periodos = [];
        foreach ($resultados as $row) {
            $periodos[] = $row['Periodo'];
        }
        return $periodos;
    }


    // Filtros dependientes
    //dependencias estados academicos
    public function getPeriodosPorEstadoAcademico($estadoAcademico) {
        $query = ' select distinct ec.Periodo
                        from estudiantesCursos ec
                        inner join estudiantes e
                            on ec.codigoEstudianteId = e.codigoEstudiante
                        inner join estados_academicos ea 
                            on e.estadoAcademicoId = ea.estadoAcademicoId   
                            ';
        $params = [];
        $conditions = $this->buildFilterConditions(['estado_academico' => $estadoAcademico],$params);

        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }
        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $periodos = [];
        foreach ($resultados as $row) {
            $periodos[] = new estudianteCurso(1, 1, 1, 1, $row['Periodo'], 1, 'sin observaciones');
        }
        return $periodos;
    }

    public function getProyectosPorEstadoAcademico($estadoAcademico) {
        $query = ' select distinct p.programaId,p.nombre,p.codigo
                    from programas p
                    inner join estudiantes e
                        on p.programaId = e.programaId
                    inner join  estados_academicos ea
                        on e.estadoAcademicoId = ea.estadoAcademicoId
                  '; 
        $params = [];

        // Quemar el valor del filtro para probar si funciona
        $conditions = $this->buildFilterConditions(['estado_academico' => $estadoAcademico],$params);

        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }
       

        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $proyectos = [];
        foreach ($resultados as $row) {
            $proyectos[] = new Programa($row['programaId'], $row['nombre'], $row['codigo']);
        }
        return $proyectos;
    }

    public function getEspaciosAcademicosPorEstadoAcademico($estadoAcademico) {
        $query = '  select distinct c.Codigo,c.Nombre
                            from cursos c
                            inner join estudiantescursos ec
                                on c.codigo = ec.codigoCursoId
                            inner join estudiantes e
                                on ec.codigoEstudianteId = e.codigoEstudiante
                            inner join estados_academicos ea
                                on e.estadoAcademicoId = ea.estadoAcademicoId
                    ';
        $params = [];
        $conditions = $this->buildFilterConditions(['estado_academico' => $estadoAcademico],$params);
        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }
        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $espacios = [];
        foreach ($resultados as $row) {
            $espacios[] = new Curso($row['Codigo'], $row['Nombre']);
        }
        return $espacios;
    }

    public function getArchivosPorEstadoAcademico($estadoAcademico) {
        $query = '  select distinct a.ArchivoId,a.NombreArchivo,a.FechaSubida,a.UsuarioId
                        from archivos a
                        inner join estudiantescursos ec
                            on a.ArchivoId = ec.ArchivoId
                        inner join estudiantes e
                            on ec.codigoEstudianteId = e.codigoEstudiante
                        inner join estados_academicos ea
                            on e.estadoAcademicoId = ea.estadoAcademicoId
                    ';
        
        $params = [];
        $conditions = $this->buildFilterConditions(['estado_academico' => $estadoAcademico],$params);
        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }
        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $archivos = [];
        foreach ($resultados as $row) {
            $archivos[] = new Archivo($row['ArchivoId'], $row['NombreArchivo'], $row['FechaSubida'], $row['UsuarioId']);
        }
        return $archivos;
    }

    // dependencias con anio y periodo
    public function getEstadosAcademicosPorPeriodo($periodo) {
        $query = '
            select distinct ea.EstadoAcademicoId,ea.EstadoAcademico,ea.NombreEstado  
            from estados_academicos ea
            inner join estudiantes e
                on ea.EstadoAcademicoId = e.EstadoAcademicoId  
            inner join estudiantescursos ec
                on e.CodigoEstudiante = ec.codigoEstudianteId  
        ';
        $params = [];
        $conditions = $this->buildFilterConditions(['periodo' => $periodo],$params);
        
        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }
        
        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $estados = [];
        foreach ($resultados as $row) {
            $estados[] = new EstadoAcademico($row['EstadoAcademicoId'], $row['EstadoAcademico'], $row['NombreEstado']);
        }
        return $estados;
    }

    public function getProyectosPorPeriodo($periodo) {
        $query = 'select distinct p.ProgramaId,p.Nombre,p.Codigo
                from programas p
                inner join estudiantes e
                    on p.ProgramaId = e.ProgramaId  
                inner join estudiantescursos ec
                on e.CodigoEstudiante = ec.CodigoEstudianteId 
                '; 
        $params = [];
        $conditions = $this->buildFilterConditions(['periodo' => $periodo],$params);
        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }

        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $proyectos = [];
        foreach ($resultados as $row) {
            $proyectos[] = new Programa($row['ProgramaId'], $row['Nombre'], $row['Codigo']);
        }
        return $proyectos;
    }

    public function getCursosPorPeriodo($periodo) {
        $query = 'select distinct c.Codigo,c.Nombre 
                            from cursos c
                            inner join estudiantescursos ec
                                on c.codigo =ec.codigoCursoId
                            ';
        $params = [];
        $conditions = $this->buildFilterConditions(['periodo' => $periodo],$params);
        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }
        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $cursos = [];
        foreach ($resultados as $row) {
            $cursos[] = new Curso($row['Codigo'], $row['Nombre']);
        }
        return $cursos;
    }

    public function getArchivosPorPeriodo($periodo) {
        $query = 'select distinct a.ArchivoId,a.NombreArchivo,a.FechaSubida,a.UsuarioId
                                from archivos a
                                inner join estudiantesCursos ec
                                    on a.ArchivoId= ec.archivoid ';
        $params = [];
        $conditions = $this->buildFilterConditions(['periodo' => $periodo],$params);
        if(!empty($conditions)){
            $query .= " WHERE " . implode(" AND ", $conditions);
        }

        $this->_db->query($query, $params);
        $this->_db->execute();
        if($this->_db->rowCount() > 0){
            $resultados = $this->_db->rows_assoc();
        }else{
            $resultados = [];
        }
        $archivos = [];
        foreach ($resultados as $row) {
            $archivos[] = new Archivo( $row['ArchivoId'],  $row['NombreArchivo'],  $row['FechaSubida'],  $row['UsuarioId']);
        }
        return $archivos;
    }

    /**
     * Método unificado para obtener todos los datos de filtros dependientes
     * @param array $filtrosActivos Filtros que ya están seleccionados
     * @return array Array con todos los datos de filtros disponibles
     */
    public function obtenerDatosFiltrosDependientes($filtrosActivos = []) {
        $resultado = [
            'periodos' => [],
            'estados_academicos' => [],
            'programas' => [],
            'cursos' => [],
            'archivos' => [],
            'estudiantes' => []
        ];

        // Query base que une todas las tablas necesarias
        $queryBase = "
            SELECT DISTINCT
                -- Periodos
                ec.Periodo,
                
                -- Estados Académicos
                ea.EstadoAcademicoId,
                ea.EstadoAcademico,
                ea.NombreEstado,
                
                -- Programas
                p.ProgramaId,
                p.Nombre as ProgramaNombre,
                p.Codigo as ProgramaCodigo,
                
                -- Cursos
                c.Codigo as CursoCodigo,
                c.Nombre as CursoNombre,
                
                -- Archivos
                a.ArchivoId,
                a.NombreArchivo,
                a.FechaSubida,
                a.UsuarioId,
                
                -- Estudiantes
                e.CodigoEstudiante,
                e.Nombre as EstudianteNombre
                
            FROM estudiantescursos ec
            INNER JOIN estudiantes e ON ec.CodigoEstudianteId = e.CodigoEstudiante
            INNER JOIN cursos c ON ec.CodigoCursoId = c.Codigo
            INNER JOIN archivos a ON ec.ArchivoId = a.ArchivoId
            LEFT JOIN programas p ON e.ProgramaId = p.ProgramaId
            LEFT JOIN estados_academicos ea ON e.EstadoAcademicoId = ea.EstadoAcademicoId
            WHERE 1=1
        ";

        $params = [];
       // echo "<script>console.log('Filtros activos: " . json_encode($filtrosActivos) . "');</script>";
        $conditions = $this->buildFilterConditions($filtrosActivos, $params);
        
        if (!empty($conditions)) {
            $queryBase .= " AND " . implode(" AND ", $conditions);
        }

        $queryBase .= " ORDER BY ec.Periodo, ea.NombreEstado, p.Nombre, c.Nombre, a.NombreArchivo, e.Nombre";

        //echo "<script>console.log('Query unificado: " . addslashes($queryBase) . "');</script>";
        //echo "<script>console.log('Params: " . json_encode($params) . "');</script>";

        $this->_db->query($queryBase, $params);
        $resultados = $this->_db->rows_assoc();

        // Procesar resultados y organizar por tipo
        $periodosUnicos = [];
        $estadosUnicos = [];
        $programasUnicos = [];
        $cursosUnicos = [];
        $archivosUnicos = [];
        $estudiantesUnicos = [];

        foreach ($resultados as $row) {
            // Periodos
            if (!empty($row['Periodo']) && !in_array($row['Periodo'], $periodosUnicos)) {
                $periodosUnicos[] = $row['Periodo'];
                $resultado['periodos'][] = ['Periodo' => $row['Periodo']];
            }

            // Estados Académicos
            if (!empty($row['EstadoAcademicoId']) && !isset($estadosUnicos[$row['EstadoAcademicoId']])) {
                $estadosUnicos[$row['EstadoAcademicoId']] = true;
                $resultado['estados_academicos'][] = [
                    'EstadoAcademicoId' => $row['EstadoAcademicoId'],
                    'EstadoAcademico' => $row['EstadoAcademico'],
                    'NombreEstado' => $row['NombreEstado']
                ];
            }

            // Programas
            if (!empty($row['ProgramaId']) && !isset($programasUnicos[$row['ProgramaId']])) {
                $programasUnicos[$row['ProgramaId']] = true;
                $resultado['programas'][] = [
                    'ProgramaId' => $row['ProgramaId'],
                    'Nombre' => $row['ProgramaNombre'],
                    'Codigo' => $row['ProgramaCodigo']
                ];
            }

            // Cursos
            if (!empty($row['CursoCodigo']) && !isset($cursosUnicos[$row['CursoCodigo']])) {
                $cursosUnicos[$row['CursoCodigo']] = true;
                $resultado['cursos'][] = [
                    'codigo' => $row['CursoCodigo'],
                    'nombre' => $row['CursoNombre']
                ];
            }

            // Archivos
            if (!empty($row['ArchivoId']) && !isset($archivosUnicos[$row['ArchivoId']])) {
                $archivosUnicos[$row['ArchivoId']] = true;
                $resultado['archivos'][] = [
                    'ArchivoId' => $row['ArchivoId'],
                    'NombreArchivo' => $row['NombreArchivo'],
                    'FechaSubida' => $row['FechaSubida'],
                    'UsuarioId' => $row['UsuarioId']
                ];
            }

            // Estudiantes
            if (!empty($row['CodigoEstudiante']) && !isset($estudiantesUnicos[$row['CodigoEstudiante']])) {
                $estudiantesUnicos[$row['CodigoEstudiante']] = true;
                $resultado['estudiantes'][] = [
                    'CodigoEstudiante' => $row['CodigoEstudiante'],
                    'Nombre' => $row['EstudianteNombre']
                ];
            }
        }

        return $resultado;
    }

    /**
     * Método simplificado para obtener datos específicos de un filtro
     * @param string $tipoFiltro Tipo de filtro (periodos, estados_academicos, programas, cursos, archivos, estudiantes)
     * @param array $filtrosActivos Filtros que ya están seleccionados
     * @return array Datos del filtro específico
     */
    public function obtenerDatosFiltroEspecifico($tipoFiltro, $filtrosActivos = []) {
        $todosDatos = $this->obtenerDatosFiltrosDependientes($filtrosActivos);
        return isset($todosDatos[$tipoFiltro]) ? $todosDatos[$tipoFiltro] : [];
    }
}
?>
