filled('nivel_dificultad')) { $query->where('nivel_dificultad', $request->nivel_dificultad); } if ($request->filled('search')) { $query->where('enunciado', 'like', '%' . $request->search . '%'); } if ($request->filled('activo') && $request->activo !== '') { $query->where('activo', $request->activo === 'true'); } $preguntas = $query ->orderBy('created_at', 'desc') ->paginate($request->get('per_page', 15)); $estadisticas = [ 'total' => Pregunta::where('curso_id', $cursoId)->count(), 'facil' => Pregunta::where('curso_id', $cursoId)->where('nivel_dificultad', 'facil')->count(), 'medio' => Pregunta::where('curso_id', $cursoId)->where('nivel_dificultad', 'medio')->count(), 'dificil' => Pregunta::where('curso_id', $cursoId)->where('nivel_dificultad', 'dificil')->count(), ]; return response()->json([ 'success' => true, 'data' => [ 'preguntas' => $preguntas, 'estadisticas' => $estadisticas ] ]); } catch (\Exception $e) { Log::error('Error obteniendo preguntas', ['error' => $e->getMessage()]); return response()->json([ 'success' => false, 'message' => 'Error al cargar preguntas' ], 500); } } public function getPregunta($id) { $pregunta = Pregunta::find($id); if (!$pregunta) { return response()->json([ 'success' => false, 'message' => 'Pregunta no encontrada' ], 404); } $pregunta->imagenes = collect($pregunta->imagenes ?? [])->map(fn($path) => $path ? url(Storage::url($path)) : null); $pregunta->imagenes_explicacion = collect($pregunta->imagenes_explicacion ?? [])->map(fn($path) => $path ? url(Storage::url($path)) : null); return response()->json([ 'success' => true, 'data' => $pregunta ]); } public function agregarPreguntaCurso(Request $request) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json(['success' => false, 'message' => 'No autorizado'], 403); } // Validación (igual que antes) $validator = Validator::make($request->all(), [ 'curso_id' => 'required|exists:cursos,id', 'enunciado' => 'required|string', 'enunciado_adicional' => 'nullable|string', 'opciones' => 'required', 'respuesta_correcta' => 'required|string', 'explicacion' => 'nullable|string', 'nivel_dificultad' => 'required|in:facil,medio,dificil', 'activo' => 'boolean', 'imagenes' => 'nullable|array', 'imagenes.*' => 'image|mimes:jpg,jpeg,png,gif,webp|max:2048', 'imagenes_explicacion' => 'nullable|array', 'imagenes_explicacion.*' => 'image|mimes:jpg,jpeg,png,gif,webp|max:2048', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } // Opciones $opciones = is_string($request->opciones) ? json_decode($request->opciones, true) : $request->opciones; $opcionesValidas = array_map('trim', $opciones); // Validar respuesta correcta if (!in_array($request->respuesta_correcta, $opcionesValidas)) { return response()->json(['success' => false, 'errors' => ['respuesta_correcta' => ['La respuesta correcta debe estar entre las opciones']]] ,422); } // Procesar imágenes del enunciado y devolver URLs completas $imagenesUrls = []; if ($request->hasFile('imagenes')) { foreach ($request->file('imagenes') as $imagen) { $path = $imagen->store('preguntas/enunciados', 'public'); $imagenesUrls[] = url(Storage::url($path)); // URL completa } } // Procesar imágenes de la explicación $imagenesExplicacionUrls = []; if ($request->hasFile('imagenes_explicacion')) { foreach ($request->file('imagenes_explicacion') as $imagen) { $path = $imagen->store('preguntas/explicaciones', 'public'); $imagenesExplicacionUrls[] = url(Storage::url($path)); // URL completa } } // Crear pregunta $pregunta = Pregunta::create([ 'curso_id' => $request->curso_id, 'enunciado' => $request->enunciado, 'enunciado_adicional' => $request->enunciado_adicional, 'opciones' => $opcionesValidas, 'respuesta_correcta' => $request->respuesta_correcta, 'explicacion' => $request->explicacion, 'nivel_dificultad' => $request->nivel_dificultad, 'activo' => $request->boolean('activo'), 'imagenes' => $imagenesUrls, 'imagenes_explicacion' => $imagenesExplicacionUrls, ]); return response()->json(['success' => true, 'message' => 'Pregunta creada correctamente', 'data' => $pregunta], 201); } catch (\Exception $e) { Log::error('Error creando pregunta', ['error' => $e->getMessage()]); return response()->json(['success' => false, 'message' => 'Error al crear la pregunta'], 500); } } public function actualizarPregunta(Request $request, $id) { try { $user = auth()->user(); if (!$user->hasRole('administrador')) { return response()->json(['success' => false, 'message' => 'No autorizado'], 403); } $pregunta = Pregunta::find($id); if (!$pregunta) { return response()->json(['success' => false, 'message' => 'Pregunta no encontrada'], 404); } // Validación $validator = Validator::make($request->all(), [ 'curso_id' => 'required|exists:cursos,id', 'enunciado' => 'required|string', 'enunciado_adicional' => 'nullable|string', 'opciones' => 'required', 'respuesta_correcta' => 'required|string', 'explicacion' => 'nullable|string', 'nivel_dificultad' => 'required|in:facil,medio,dificil', 'activo' => 'boolean', 'imagenes' => 'nullable|array', 'imagenes.*' => 'image|mimes:jpg,jpeg,png,gif,webp|max:2048', 'imagenes_explicacion' => 'nullable|array', 'imagenes_explicacion.*' => 'image|mimes:jpg,jpeg,png,gif,webp|max:2048', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } // Decodificar opciones $opciones = is_string($request->opciones) ? json_decode($request->opciones, true) : $request->opciones; $opcionesValidas = array_map('trim', $opciones); if (!in_array($request->respuesta_correcta, $opcionesValidas)) { return response()->json([ 'success' => false, 'errors' => ['respuesta_correcta' => ['La respuesta correcta debe estar entre las opciones']] ], 422); } // --- Imágenes del enunciado --- $imagenesActuales = $request->input('imagenes_existentes', $pregunta->imagenes ?? []); if (is_string($imagenesActuales)) { $imagenesActuales = json_decode($imagenesActuales, true) ?? []; } if ($request->hasFile('imagenes')) { foreach ($request->file('imagenes') as $imagen) { $path = $imagen->store('preguntas/enunciados', 'public'); $imagenesActuales[] = url(Storage::url($path)); } } // --- Imágenes de la explicación --- $imagenesExplicacionActuales = $request->input('imagenes_explicacion_existentes', $pregunta->imagenes_explicacion ?? []); if (is_string($imagenesExplicacionActuales)) { $imagenesExplicacionActuales = json_decode($imagenesExplicacionActuales, true) ?? []; } if ($request->hasFile('imagenes_explicacion')) { foreach ($request->file('imagenes_explicacion') as $imagen) { $path = $imagen->store('preguntas/explicaciones', 'public'); $imagenesExplicacionActuales[] = url(Storage::url($path)); } } // Actualizar pregunta $pregunta->update([ 'curso_id' => $request->curso_id, 'enunciado' => $request->enunciado, 'enunciado_adicional' => $request->enunciado_adicional, 'opciones' => $opcionesValidas, 'respuesta_correcta' => $request->respuesta_correcta, 'explicacion' => $request->explicacion, 'nivel_dificultad' => $request->nivel_dificultad, 'activo' => $request->boolean('activo'), 'imagenes' => $imagenesActuales, 'imagenes_explicacion' => $imagenesExplicacionActuales, ]); return response()->json([ 'success' => true, 'message' => 'Pregunta actualizada correctamente', 'data' => $pregunta ]); } catch (\Exception $e) { Log::error('Error actualizando pregunta', ['error' => $e->getMessage()]); return response()->json([ 'success' => false, 'message' => 'Error al actualizar la pregunta' ], 500); } } public function eliminarPregunta($id) { $pregunta = Pregunta::find($id); if (!$pregunta) { return response()->json([ 'success' => false, 'message' => 'Pregunta no encontrada' ], 404); } // Eliminar imágenes del storage si existen if ($pregunta->imagenes) { foreach ($pregunta->imagenes as $imagen) { Storage::disk('public')->delete($imagen); } } if ($pregunta->imagenes_explicacion) { foreach ($pregunta->imagenes_explicacion as $imagen) { Storage::disk('public')->delete($imagen); } } $pregunta->delete(); return response()->json([ 'success' => true, 'message' => 'Pregunta eliminada correctamente' ]); } }