import 'dart:async'; import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import '../database/app_database.dart'; import '../models/remote_command.dart'; import '../services/remote_sync_service.dart'; import '../utils/app_config.dart'; class RemoteSyncViewModel extends ChangeNotifier { final RemoteSyncService syncService; RemoteSyncViewModel({required this.syncService}) { _eventSubscription = syncService.events.listen(_onEvent); } StreamSubscription? _eventSubscription; List _recentEvents = []; List get recentEvents => _recentEvents; bool _isSyncing = false; bool get isSyncing => _isSyncing; bool _isConfigured = false; bool get isConfigured => _isConfigured; DateTime? _lastSyncAt; DateTime? get lastSyncAt => _lastSyncAt; String? _lastError; String? get lastError => _lastError; String? _venueId; String? get venueId => _venueId; List _activity = []; List get activity => _activity; bool _isRegistering = false; bool get isRegistering => _isRegistering; String? _registrationError; String? get registrationError => _registrationError; Future init() async { _isConfigured = await syncService.isConfigured; _venueId = await syncService.venueId; _lastSyncAt = await syncService.lastSuccessfulSyncAt; await loadActivity(); if (_isConfigured) { syncService.startPeriodicSync(); } notifyListeners(); } Future refreshStatus() async { _isConfigured = await syncService.isConfigured; _venueId = await syncService.venueId; notifyListeners(); } Future syncNow() async { _isSyncing = true; _lastError = null; notifyListeners(); await syncService.sync(); _isSyncing = syncService.isSyncing; _lastSyncAt = await syncService.lastSuccessfulSyncAt; await loadActivity(); notifyListeners(); } Future loadActivity() async { try { _activity = await syncService.getRecentActivity(); } catch (e) { debugPrint('RemoteSyncViewModel: loadActivity error: $e'); } } Future registerDevice({ required String venueId, required String deviceName, required String registrationCode, }) async { _isRegistering = true; _registrationError = null; notifyListeners(); try { final response = await http.post( Uri.parse('$kRemoteServerUrl/devices/register'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({ 'venueId': venueId, 'name': deviceName, 'registrationCode': registrationCode, }), ).timeout(const Duration(seconds: 15)); if (response.statusCode == 201) { final data = jsonDecode(response.body) as Map; final deviceId = data['deviceId'] as String; final token = data['token'] as String; await syncService.setCredentials( deviceId: deviceId, token: token, venueId: venueId, serverUrl: kRemoteServerUrl, ); _isConfigured = true; _venueId = venueId; _isRegistering = false; notifyListeners(); syncService.startPeriodicSync(); await syncNow(); return true; } else { final body = response.body; String message; try { final errorData = jsonDecode(body) as Map; message = errorData['message'] as String? ?? 'Registration failed'; } catch (_) { message = 'Registration failed (HTTP ${response.statusCode})'; } _registrationError = message; _isRegistering = false; notifyListeners(); return false; } } catch (e) { debugPrint('RemoteSyncViewModel: registration error: $e'); _registrationError = e.toString(); _isRegistering = false; notifyListeners(); return false; } } Future unlink() async { syncService.stopPeriodicSync(); await syncService.clearCredentials(); _isConfigured = false; _venueId = null; _lastSyncAt = null; _lastError = null; _recentEvents = []; _activity = []; notifyListeners(); } void startSync() { syncService.startPeriodicSync(); syncNow(); } void _onEvent(RemoteSyncEvent event) { _recentEvents = [event, ..._recentEvents.take(49)]; _lastSyncAt = DateTime.now(); if (event.type == RemoteSyncEventType.syncFailed) { _lastError = event.message; } else if (event.type == RemoteSyncEventType.syncCompleted) { _lastError = null; } notifyListeners(); } void pause() { syncService.pause(); } void resume() { syncService.resume(); syncNow(); } @override void dispose() { _eventSubscription?.cancel(); syncService.dispose(); super.dispose(); } }