import 'dart:async'; import 'package:flutter/material.dart'; import 'package:firebase_database/firebase_database.dart'; import '../services/firebase_service.dart'; class ACSetupProvider extends ChangeNotifier { // Status from Firebase String _mode = 'idle'; // idle, config, sweep, learn String _step = 'not_configured'; // not_configured, select_brand, confirm, learning, ready bool _hasSavedConfig = false; int _brandIndex = 0; String _brandName = ''; String _brandDesc = ''; String _modelName = ''; String _message = ''; // Detected in learning String _detectedProtocol = ''; String _detectedDesc = ''; // Brands list from Firebase List> _brands = []; // Getters String get mode => _mode; String get step => _step; bool get hasSavedConfig => _hasSavedConfig; int get brandIndex => _brandIndex; String get brandName => _brandName; String get brandDesc => _brandDesc; String get modelName => _modelName; String get message => _message; String get detectedProtocol => _detectedProtocol; String get detectedDesc => _detectedDesc; List> get brands => _brands; StreamSubscription? _statusSubscription; StreamSubscription? _brandsSubscription; bool _isSending = false; bool get isSending => _isSending; void startListening() { _statusSubscription?.cancel(); _brandsSubscription?.cancel(); // 1. Listen to config status _statusSubscription = FirebaseService.acConfigStatusRef.onValue.listen((event) { if (event.snapshot.value == null) { _mode = 'idle'; _step = 'not_configured'; _hasSavedConfig = false; _brandIndex = 0; _brandName = ''; _brandDesc = ''; _modelName = ''; _message = ''; _detectedProtocol = ''; _detectedDesc = ''; } else { final data = Map.from(event.snapshot.value as Map); _mode = data['mode']?.toString() ?? 'idle'; _step = data['step']?.toString() ?? 'not_configured'; _hasSavedConfig = data['has_config'] == true; _brandIndex = int.tryParse(data['brand_index']?.toString() ?? '0') ?? 0; _brandName = data['brand_name']?.toString() ?? ''; _brandDesc = data['brand_desc']?.toString() ?? ''; _modelName = data['model_name']?.toString() ?? ''; _message = data['message']?.toString() ?? ''; _detectedProtocol = data['detected_protocol']?.toString() ?? ''; _detectedDesc = data['detected_desc']?.toString() ?? ''; } notifyListeners(); }); // 2. Listen to config brands _brandsSubscription = FirebaseService.acConfigBrandsRef.onValue.listen((event) { if (event.snapshot.value == null) { _brands = []; } else { final rawList = event.snapshot.value; if (rawList is List) { _brands = rawList .where((item) => item != null) .map((item) => Map.from(item as Map)) .toList(); } else if (rawList is Map) { _brands = rawList.values .where((item) => item != null) .map((item) => Map.from(item as Map)) .toList(); } else { _brands = []; } } notifyListeners(); }); } Future _sendCommand(String cmd, String val) async { try { _isSending = true; notifyListeners(); await FirebaseService.acCommandRef.set({ 'command': cmd, 'value': val, 'timestamp': ServerValue.timestamp, }); _isSending = false; notifyListeners(); } catch (e) { _isSending = false; notifyListeners(); rethrow; } } Future startConfigMode() async { await _sendCommand('config', ''); } Future selectBrand(int index) async { await _sendCommand('select_brand', index.toString()); } Future confirm(String value) async { await _sendCommand('confirm', value); } Future cancelConfig() async { await _sendCommand('cancel_config', ''); } Future saveConfig() async { await _sendCommand('save_config', ''); } Future clearConfig() async { await _sendCommand('clear_config', ''); } Future startLearnMode() async { await _sendCommand('learn', ''); } Future sendRaw() async { await _sendCommand('sendraw', ''); } @override void dispose() { _statusSubscription?.cancel(); _brandsSubscription?.cancel(); super.dispose(); } }