id; // Verificar si está en Redis $enRedis = Redis::get($key); if ($enRedis) { // Ya está marcado como robado, verificar si sigue así $resultado = $this->verificarVehiculoRobado($epc, json_decode($enRedis, true)); $this->registrarDeteccion($epc, $resultado, $arcoId); return $resultado; } // No está en Redis, consultar servicios $resultado = $this->consultarNuevoVehiculo($epc, $fastId); $this->registrarDeteccion($epc, $resultado, $arcoId); return $resultado; } private function consultarNuevoVehiculo(string $epc, string $fastId): array { // Consultar con FastID (tag_number) $datosVehiculo = $this->consultaRepuveCons->consultarVehiculoPorTag($fastId); if (!$datosVehiculo || !$datosVehiculo['vin']) { Log::warning('Vehículo NO encontrado en API externa', [ 'epc' => $epc, 'fast_id' => $fastId ]); return [ 'success' => false, 'message' => 'No se encontró información del vehículo en la API externa' ]; } // Consultar REPUVE para verificar si está robado $reporteRobo = $this->reporteRobo->consultarRobado( $datosVehiculo['vin'], $datosVehiculo['placa'] ); if ($reporteRobo['tiene_reporte']) { // Está robado → Guardar en Redis $this->guardarEnRedis($epc, $datosVehiculo, $reporteRobo['datos']); Log::warning('¡VEHÍCULO ROBADO DETECTADO!', [ 'epc' => $epc, 'fast_id' => $fastId, 'vin' => $datosVehiculo['vin'], 'placa' => $datosVehiculo['placa'] ]); return [ 'success' => true, 'tiene_reporte_robo' => true, 'estado' => 'ROBADO', 'accion' => 'GUARDADO EN BD DE ROBADOS', 'vehiculo' => array_merge($datosVehiculo, $reporteRobo['datos']) ]; } // No está robado - vehículo LIBRE Log::info('Vehículo detectado - LIBRE (sin reporte de robo)', [ 'epc' => $epc, 'fast_id' => $fastId, 'vin' => $datosVehiculo['vin'], 'placa' => $datosVehiculo['placa'] ]); return [ 'success' => true, 'tiene_reporte_robo' => false, 'estado' => 'LIBRE', 'vehiculo' => $datosVehiculo ]; } private function verificarVehiculoRobado(string $epc, array $datosRedis): array { // Consultar REPUVE para verificar estado actual $reporteRobo = $this->reporteRobo->consultarRobado( $datosRedis['vin'], $datosRedis['placa'] ); if (!$reporteRobo['tiene_reporte']) { // No tiene reporte robo - RECUPERADO $this->registrarRecuperacion($epc, $datosRedis); Log::info('¡VEHÍCULO RECUPERADO!', [ 'epc' => $epc, 'vin' => $datosRedis['vin'], 'placa' => $datosRedis['placa'] ]); return [ 'success' => true, 'tiene_reporte_robo' => false, 'estado' => 'RECUPERADO', 'accion' => 'GUARDADO EN RECUPERADOS Y ELIMINADO DE ROBADOS', 'vehiculo' => $datosRedis ]; } // Sigue robado → Actualizar contador en Redis $this->actualizarDeteccionRedis($epc, $datosRedis); Log::warning('Vehículo robado detectado nuevamente', [ 'epc' => $epc, 'detecciones' => $datosRedis['detecciones'] + 1 ]); return [ 'success' => true, 'tiene_reporte_robo' => true, 'estado' => 'ROBADO', 'accion' => 'ACTUALIZADO_EN_REDIS', 'vehiculo' => $datosRedis ]; } private function guardarEnRedis(string $epc, array $datosEstatal, array $datosRobo) { $key = "vehiculo:robado:{$epc}"; $datos = [ 'epc' => $epc, 'vin' => $datosEstatal['vin'], 'placa' => $datosEstatal['placa'], 'fecha_robo' => $datosRobo['fecha_robo'] ?? null, 'autoridad' => $datosRobo['autoridad'] ?? null, 'acta' => $datosRobo['acta'] ?? null, 'denunciante' => $datosRobo['denunciante'] ?? null, 'fecha_acta' => $datosRobo['fecha_acta'] ?? null, 'primera_deteccion' => now()->toIso8601String(), 'ultima_deteccion' => now()->toIso8601String(), 'detecciones' => 1 ]; Redis::set($key, json_encode($datos)); } private function actualizarDeteccionRedis(string $epc, array $datosActuales) { $key = "vehiculo:robado:{$epc}"; $datosActuales['ultima_deteccion'] = now()->toIso8601String(); $datosActuales['detecciones'] = ($datosActuales['detecciones'] ?? 0) + 1; Redis::set($key, json_encode($datosActuales)); } private function registrarRecuperacion(string $epc, array $datosRedis) { // Guardar en MySQL Vehicle::create([ 'epc' => $epc, 'vin' => $datosRedis['vin'], 'placa' => $datosRedis['placa'], 'fecha_robo' => $datosRedis['fecha_robo'], 'autoridad_robo' => $datosRedis['autoridad'], 'acta_robo' => $datosRedis['acta'], 'denunciante' => $datosRedis['denunciante'], 'fecha_recuperacion' => now(), 'fecha_acta' => $datosRedis['fecha_acta'] ?? null, 'datos_robo_original' => $datosRedis ]); // Eliminar de Redis Redis::del("vehiculo:robado:{$epc}"); } public function listarVehiculosRobados(): array { $keys = Redis::keys('vehiculo:robado:*'); $vehiculos = []; foreach ($keys as $key) { $datos = Redis::get($key); if ($datos) { $vehiculos[] = json_decode($datos, true); } } return $vehiculos; } private function registrarDeteccion(string $epc, array $resultado, ?int $arcoId = null) { if (!$resultado['success'] || !isset($resultado['vehiculo'])) { return; } $vehiculo = $resultado['vehiculo']; Detection::create([ 'arco_id' => $arcoId, 'epc' => $epc, 'vin' => $vehiculo['vin'] ?? null, 'placa' => $vehiculo['placa'] ?? null, 'marca' => $vehiculo['marca'] ?? null, 'modelo' => $vehiculo['modelo'] ?? null, 'color' => $vehiculo['color'] ?? null, 'fecha_deteccion' => now() ]); } /** * Consultar vehículo por tag_id */ public function consultarVehiculoPorTag(?string $epc = null, ?string $tagId = null) { try { // Validar que se proporcionó tag_id if (empty($tagId)) { Log::warning('VehicleService: No se proporcionó tag_id'); return null; } $vehiculoExterno = $this->consultaRepuveCons->consultarVehiculoPorTag($tagId); if ($vehiculoExterno) { Log::info('VehicleService: Vehículo encontrado', [ 'tag_id' => $vehiculoExterno['tag_id'] ?? null, 'tag_number' => $vehiculoExterno['tag_number'] ?? null, 'vin' => $vehiculoExterno['vin'] ?? null ]); } else { Log::info('VehicleService: Vehículo no encontrado', [ 'tag_id' => $tagId ]); } return $vehiculoExterno; } catch (\Exception $e) { Log::error('VehicleService: Error en consulta', [ 'tag_id' => $tagId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return null; } } }