user(); if (!$user->hasRole('administrador')) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } $academia = Academia::where('admin_academia_id', $user->id)->first(); if (!$academia) { return response()->json([ 'success' => false, 'message' => 'Academia no encontrada' ], 404); } $query = $academia->examenes() ->withCount(['preguntas', 'intentos' => function($query) { $query->where('estado', 'finalizado'); }]) ->latest(); if ($request->has('search')) { $search = $request->search; $query->where('titulo', 'like', "%{$search}%"); } if ($request->has('publicado')) { $query->where('publicado', $request->publicado); } if ($request->has('tipo')) { $query->where('tipo', $request->tipo); } $examenes = $query->paginate(15); return response()->json([ 'success' => true, 'data' => $examenes ]); } catch (\Exception $e) { Log::error('Error obteniendo exámenes', [ 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Error al cargar los exámenes' ], 500); } } public function crearExamen(Request $request) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } $academia = Academia::where('admin_academia_id', $user->id)->first(); if (!$academia) { return response()->json([ 'success' => false, 'message' => 'Academia no encontrada' ], 404); } $validator = Validator::make($request->all(), [ 'titulo' => 'required|string|max:255', 'descripcion' => 'nullable|string', 'tipo' => 'required|in:practica,simulacro,evaluacion', 'dificultad' => 'required|in:facil,medio,dificil,avanzado', 'duracion_minutos' => 'required|integer|min:1|max:480', 'intentos_permitidos' => 'required|integer|min:1|max:10', 'puntaje_minimo' => 'required|numeric|min:0|max:100', 'preguntas_aleatorias' => 'boolean', 'mostrar_resultados' => 'boolean', 'mostrar_respuestas' => 'boolean', 'publicado' => 'boolean', 'fecha_inicio' => 'nullable|date', 'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio', 'configuracion' => 'nullable|array' ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'errors' => $validator->errors() ], 422); } DB::beginTransaction(); $examen = Examen::create([ 'academia_id' => $academia->id, 'titulo' => $request->titulo, 'descripcion' => $request->descripcion, 'tipo' => $request->tipo, 'dificultad' => $request->dificultad, 'duracion_minutos' => $request->duracion_minutos, 'intentos_permitidos' => $request->intentos_permitidos, 'puntaje_minimo' => $request->puntaje_minimo, 'preguntas_aleatorias' => $request->preguntas_aleatorias ?? 0, 'mezclar_opciones' => $request->mezclar_opciones ?? true, 'mostrar_resultados' => $request->mostrar_resultados ?? true, 'mostrar_respuestas' => $request->mostrar_respuestas ?? false, 'mostrar_explicaciones' => $request->mostrar_explicaciones ?? false, 'activar_timer' => $request->activar_timer ?? true, 'permitir_navegacion' => $request->permitir_navegacion ?? true, 'permitir_revisar' => $request->permitir_revisar ?? true, 'publicado' => $request->publicado ?? false, 'fecha_inicio' => $request->fecha_inicio, 'fecha_fin' => $request->fecha_fin, 'orden' => $request->orden ?? 1, 'configuracion' => $request->configuracion ?? [] ]); DB::commit(); Log::info('Examen creado por admin', [ 'academia_id' => $academia->id, 'examen_id' => $examen->id, 'admin_id' => $user->id ]); return response()->json([ 'success' => true, 'message' => 'Examen creado exitosamente', 'data' => $examen ], 201); } catch (\Exception $e) { DB::rollBack(); Log::error('Error creando examen', [ 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Error al crear el examen' ], 500); } } public function getExamen($examenId) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } $academia = Academia::where('admin_academia_id', $user->id)->first(); if (!$academia) { return response()->json([ 'success' => false, 'message' => 'Academia no encontrada' ], 404); } $examen = Examen::where('academia_id', $academia->id) ->with(['preguntas']) ->find($examenId); if (!$examen) { return response()->json([ 'success' => false, 'message' => 'Examen no encontrado' ], 404); } $estadisticas = DB::table('intentos_examen') ->where('examen_id', $examenId) ->where('estado', 'finalizado') ->selectRaw('COUNT(*) as total_intentos') ->selectRaw('AVG(porcentaje) as promedio') ->selectRaw('SUM(CASE WHEN aprobado = 1 THEN 1 ELSE 0 END) as aprobados') ->first(); return response()->json([ 'success' => true, 'data' => [ 'examen' => $examen, 'estadisticas' => $estadisticas ] ]); } catch (\Exception $e) { Log::error('Error obteniendo examen', [ 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Error al cargar el examen' ], 500); } } public function actualizarExamen(Request $request, $examenId) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } $academia = Academia::where('admin_academia_id', $user->id)->first(); if (!$academia) { return response()->json([ 'success' => false, 'message' => 'Academia no encontrada' ], 404); } $examen = Examen::where('academia_id', $academia->id)->find($examenId); if (!$examen) { return response()->json([ 'success' => false, 'message' => 'Examen no encontrado' ], 404); } $validator = Validator::make($request->all(), [ 'titulo' => 'sometimes|string|max:255', 'descripcion' => 'nullable|string', 'tipo' => 'sometimes|in:practica,simulacro,evaluacion', 'duracion_minutos' => 'sometimes|integer|min:1|max:480', 'intentos_permitidos' => 'sometimes|integer|min:1|max:10', 'puntaje_minimo' => 'sometimes|numeric|min:0|max:100', 'preguntas_aleatorias' => 'boolean', 'mostrar_resultados' => 'boolean', 'mostrar_respuestas' => 'boolean', 'publicado' => 'boolean', 'fecha_inicio' => 'nullable|date', 'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio', 'configuracion' => 'nullable|array' ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'errors' => $validator->errors() ], 422); } $examen->update($request->only([ 'titulo', 'descripcion', 'tipo', 'duracion_minutos', 'intentos_permitidos', 'puntaje_minimo', 'preguntas_aleatorias', 'mostrar_resultados', 'mostrar_respuestas', 'publicado', 'fecha_inicio', 'fecha_fin', 'configuracion' ])); Log::info('Examen actualizado por admin', [ 'academia_id' => $academia->id, 'examen_id' => $examen->id, 'admin_id' => $user->id ]); return response()->json([ 'success' => true, 'message' => 'Examen actualizado exitosamente', 'data' => $examen ]); } catch (\Exception $e) { Log::error('Error actualizando examen', [ 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Error al actualizar el examen' ], 500); } } public function eliminarExamen($examenId) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } $academia = Academia::where('admin_academia_id', $user->id)->first(); if (!$academia) { return response()->json([ 'success' => false, 'message' => 'Academia no encontrada' ], 404); } $examen = Examen::where('academia_id', $academia->id)->find($examenId); if (!$examen) { return response()->json([ 'success' => false, 'message' => 'Examen no encontrado' ], 404); } $tieneIntentos = $examen->intentos()->exists(); if ($tieneIntentos) { return response()->json([ 'success' => false, 'message' => 'No se puede eliminar un examen con intentos realizados' ], 400); } $examen->delete(); Log::info('Examen eliminado por admin', [ 'academia_id' => $academia->id, 'examen_id' => $examenId, 'admin_id' => $user->id ]); return response()->json([ 'success' => true, 'message' => 'Examen eliminado exitosamente' ]); } catch (\Exception $e) { Log::error('Error eliminando examen', [ 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Error al eliminar el examen' ], 500); } } public function getResultadosExamen($examenId) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } $academia = Academia::where('admin_academia_id', $user->id)->first(); if (!$academia) { return response()->json([ 'success' => false, 'message' => 'Academia no encontrada' ], 404); } $examen = Examen::where('academia_id', $academia->id)->find($examenId); if (!$examen) { return response()->json([ 'success' => false, 'message' => 'Examen no encontrado' ], 404); } $resultados = DB::table('intentos_examen') ->join('users', 'intentos_examen.user_id', '=', 'users.id') ->where('intentos_examen.examen_id', $examenId) ->where('intentos_examen.estado', 'finalizado') ->select( 'users.id as estudiante_id', 'users.name as estudiante_nombre', 'users.email as estudiante_email', 'intentos_examen.numero_intento', 'intentos_examen.porcentaje', 'intentos_examen.aprobado', 'intentos_examen.tiempo_utilizado', 'intentos_examen.finalizado_en' ) ->orderBy('intentos_examen.porcentaje', 'desc') ->get(); $estadisticas = [ 'total_estudiantes' => $resultados->groupBy('estudiante_id')->count(), 'promedio' => $resultados->avg('porcentaje'), 'aprobados' => $resultados->where('aprobado', true)->count(), 'reprobados' => $resultados->where('aprobado', false)->count(), 'tiempo_promedio' => $resultados->avg('tiempo_utilizado') ]; return response()->json([ 'success' => true, 'data' => [ 'resultados' => $resultados, 'estadisticas' => $estadisticas ] ]); } catch (\Exception $e) { Log::error('Error obteniendo resultados', [ 'error' => $e->getMessage() ]); return response()->json([ 'success' => false, 'message' => 'Error al cargar los resultados' ], 500); } } }