has('activo')) { $query->where('activo', $request->boolean('activo')); } // Filtro por IP if ($request->has('ip')) { $query->where('ip_address', 'like', '%' . $request->ip . '%'); } $arcos = $query->orderBy('created_at', 'desc')->get(); // Agregar token desencriptado a cada arco $arcos->each(function($arco) { $arco->api_token_plain = $arco->obtenerTokenDesencriptado(); }); return ApiResponse::OK->response([ 'arcos' => $arcos, ]); } /** * Crear un nuevo arco * POST /api/arcos */ public function store(Request $request) { $validated = $request->validate([ 'nombre' => 'required|string|max:255', 'ip_address' => 'required|ip|unique:arcos,ip_address', 'ubicacion' => 'nullable|string|max:255', 'descripcion' => 'nullable|string', 'antena_1' => 'nullable|string', 'antena_2' => 'nullable|string', 'antena_3' => 'nullable|string', 'antena_4' => 'nullable|string', 'activo' => 'boolean' ]); $arco = Arco::create($validated); // Obtener el token en texto plano para mostrárselo al usuario $plainToken = $arco->obtenerTokenDesencriptado(); return ApiResponse::CREATED->response([ 'message' => 'Arco creado exitosamente', 'arco' => $arco, 'api_token' => $plainToken // Token en texto plano para que el arco lo use ]); } /** * Mostrar un arco específico * GET /api/arcos/{id} */ public function show(Arco $arco) { return ApiResponse::OK->response([ 'arco' => $arco ]); } /** * Actualizar un arco * PUT/PATCH /api/arcos/{id} */ public function update(Request $request, int $id) { $arco = Arco::find($id); if (!$arco) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Arco no encontrado' ]); } $validated = $request->validate([ 'nombre' => 'sometimes|required|string|max:255', 'ip_address' => 'sometimes|required|ip|unique:arcos,ip_address,' . $id, 'ubicacion' => 'nullable|string|max:255', 'descripcion' => 'nullable|string', 'antena_1' => 'nullable|string', 'antena_2' => 'nullable|string', 'antena_3' => 'nullable|string', 'antena_4' => 'nullable|string' ]); $arco->update($validated); return ApiResponse::OK->response([ 'message' => 'Arco actualizado exitosamente', 'arco' => $arco ]); } /** * Eliminar un arco * DELETE /api/arcos/{id} */ public function destroy(int $id) { $arco = Arco::find($id); if (!$arco) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Arco no encontrado' ]); } $arco->delete(); return ApiResponse::OK->response([ 'message' => 'Arco eliminado exitosamente' ]); } /** * Activar/Desactivar un arco * PATCH /api/arcos/{id}/toggle-estado */ public function toggleEstado(int $id) { $arco = Arco::find($id); if (!$arco) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Arco no encontrado' ]); } $arco->activo = !$arco->activo; $arco->save(); return ApiResponse::OK->response([ 'message' => $arco->activo ? 'Arco activado' : 'Arco desactivado', 'arco' => $arco ]); } /** * Listar detecciones del día de un arco específico * GET /api/arcos/{id}/detecciones/dia */ public function deteccionesDelDia(Request $request, int $id) { $arco = Arco::find($id); if (!$arco) { return ApiResponse::NOT_FOUND->response([ 'success' => false, 'message' => 'Arco no encontrado' ]); } $fecha = $request->input('fecha'); // Formato: Y-m-d (opcional) if ($fecha && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) { return ApiResponse::BAD_REQUEST->response([ 'success' => false, 'message' => 'Formato de fecha inválido. Use YYYY-MM-DD' ]); } try { $detecciones = $this->vehicleService->listarDeteccionesDelDiaPorArco($id, $fecha); // Filtrar solo VIN, placa, antena y si es robado $deteccionesFiltradas = array_map(function($deteccion) { return [ 'vin' => $deteccion['vin'] ?? null, 'placa' => $deteccion['placa'] ?? null, 'antena' => $deteccion['antena'] ?? null, 'robado' => $deteccion['tiene_reporte_robo'] ?? false, ]; }, $detecciones); return ApiResponse::OK->response([ 'success' => true, 'arco' => [ 'id' => $arco->id, 'nombre' => $arco->nombre, 'ubicacion' => $arco->ubicacion, ], 'fecha' => $fecha ?? now()->format('Y-m-d'), 'total' => count($deteccionesFiltradas), 'detecciones' => $deteccionesFiltradas ]); } catch (\Exception $e) { return ApiResponse::INTERNAL_ERROR->response([ 'success' => false, 'message' => 'Error al obtener detecciones del arco', 'error' => $e->getMessage() ]); } } }