import 'dart:async'; import 'package:flutter/material.dart'; import 'api.dart'; /// Service that polls the backend API for order status updates /// Uses a simple polling approach (Option 2) with 30-second intervals class OrderPollingService { static Timer? _pollingTimer; static int? _currentOrderId; static int? _lastKnownStatusId; static Function(OrderStatusUpdate)? _onStatusUpdate; /// Start polling for order status updates static void startPolling({ required int orderId, required int initialStatusId, required Function(OrderStatusUpdate) onStatusUpdate, }) { print('[OrderPolling] 🔄 Starting polling for OrderID=$orderId, Status=$initialStatusId'); // Stop any existing polling stopPolling(); _currentOrderId = orderId; _lastKnownStatusId = initialStatusId; _onStatusUpdate = onStatusUpdate; // Poll every 30 seconds _pollingTimer = Timer.periodic(const Duration(seconds: 30), (_) { _checkForUpdate(); }); // Also check immediately _checkForUpdate(); } /// Stop polling static void stopPolling() { print('[OrderPolling] âšī¸ Stopping polling'); _pollingTimer?.cancel(); _pollingTimer = null; _currentOrderId = null; _lastKnownStatusId = null; _onStatusUpdate = null; } /// Check if currently polling static bool get isPolling => _pollingTimer != null && _pollingTimer!.isActive; /// Get current order ID being polled static int? get currentOrderId => _currentOrderId; /// Internal method to check for updates static Future _checkForUpdate() async { if (_currentOrderId == null || _lastKnownStatusId == null) { print('[OrderPolling] âš ī¸ No order to poll, stopping'); stopPolling(); return; } try { print('[OrderPolling] 🔍 Checking status for OrderID=$_currentOrderId'); final data = await Api.checkOrderStatus( orderId: _currentOrderId!, lastKnownStatusId: _lastKnownStatusId!, ); if (data['OK'] == true && data['HAS_UPDATE'] == true) { final orderStatus = data['ORDER_STATUS']; final newStatusId = (orderStatus['StatusID'] as num).toInt(); final statusName = orderStatus['StatusName'] as String; final message = orderStatus['Message'] as String; print('[OrderPolling] ✅ Status update detected: $statusName (ID=$newStatusId)'); // Update last known status _lastKnownStatusId = newStatusId; // Notify listener if (_onStatusUpdate != null) { _onStatusUpdate!(OrderStatusUpdate( orderId: _currentOrderId!, statusId: newStatusId, statusName: statusName, message: message, )); } } else { print('[OrderPolling] â„šī¸ No status update'); } } catch (e) { print('[OrderPolling] ❌ Error checking status: $e'); } } } /// Data class representing an order status update class OrderStatusUpdate { final int orderId; final int statusId; final String statusName; final String message; const OrderStatusUpdate({ required this.orderId, required this.statusId, required this.statusName, required this.message, }); @override String toString() => 'OrderStatusUpdate(orderId: $orderId, statusId: $statusId, statusName: $statusName, message: $message)'; }