import 'dart:convert'; import 'package:flutter/foundation.dart'; /// Tipos de mensajes en el protocolo P2P enum TipoMensaje { salaInfo, partidaInicio, fase, votacionResultado, partidaFin, unirse, voto, listo, } /// Mensaje del protocolo P2P entre dispositivos class MensajeP2P { final TipoMensaje tipo; final Map datos; MensajeP2P({required this.tipo, required this.datos}); String toJson() => json.encode({ 'tipo': tipo.name, 'datos': datos, }); factory MensajeP2P.fromJson(String jsonStr) { final mapa = json.decode(jsonStr) as Map; return MensajeP2P( tipo: TipoMensaje.values.firstWhere((t) => t.name == mapa['tipo']), datos: mapa['datos'] as Map, ); } } /// Servicio para conexiones P2P usando Google Nearby Connections API. /// /// Este servicio encapsula toda la lógica de Nearby Connections. /// Requiere dispositivos Android físicos para funcionar. /// En la versión actual, se provee la estructura para integración futura. class ServicioNearby extends ChangeNotifier { bool _esHost = false; bool _conectado = false; String? _endpointId; final List _dispositivos = []; bool get esHost => _esHost; bool get conectado => _conectado; String? get endpointId => _endpointId; List get dispositivos => List.unmodifiable(_dispositivos); /// Inicia como host (anunciando el endpoint) Future iniciarHost(String nombreSala) async { // Nota: nearby_connections requiere permisos de ubicación y Bluetooth // que deben solicitarse antes de iniciar. // Implementación con el paquete nearby_connections: // // try { // await Nearby().startAdvertising( // nombreSala, // Strategy.P2P_STAR, // onConnectionInitiated: _onConexionIniciada, // onConnectionResult: _onResultadoConexion, // onDisconnected: _onDesconexion, // serviceId: 'es.freetimelab.farolero', // ); // _esHost = true; // _endpointId = nombreSala; // notifyListeners(); // return true; // } catch (e) { // debugPrint('Error iniciando host: $e'); // return false; // } _esHost = true; _endpointId = nombreSala; notifyListeners(); return true; } /// Conecta a un host escaneado via QR Future conectarAHost(String endpointId, String nombre) async { // Implementación con el paquete nearby_connections: // // try { // await Nearby().startDiscovery( // nombre, // Strategy.P2P_STAR, // onEndpointFound: (id, name, serviceId) { // Nearby().requestConnection(nombre, id, // onConnectionInitiated: _onConexionIniciada, // onConnectionResult: _onResultadoConexion, // onDisconnected: _onDesconexion, // ); // }, // onEndpointLost: (id) {}, // serviceId: 'es.freetimelab.farolero', // ); // return true; // } catch (e) { // debugPrint('Error conectando: $e'); // return false; // } _conectado = true; notifyListeners(); return true; } /// Envía un mensaje a un dispositivo específico Future enviarMensaje(String endpointId, MensajeP2P mensaje) async { // Implementación: // final bytes = Uint8List.fromList(utf8.encode(mensaje.toJson())); // await Nearby().sendBytesPayload(endpointId, bytes); debugPrint('Enviar a $endpointId: ${mensaje.toJson()}'); } /// Envía un mensaje a todos los dispositivos conectados Future enviarATodos(MensajeP2P mensaje) async { for (final id in _dispositivos) { await enviarMensaje(id, mensaje); } } /// Desconecta y limpia Future desconectar() async { // await Nearby().stopAllEndpoints(); // await Nearby().stopAdvertising(); // await Nearby().stopDiscovery(); _esHost = false; _conectado = false; _endpointId = null; _dispositivos.clear(); notifyListeners(); } /// Genera los datos para el código QR de conexión String generarDatosQR(String nombreSala) { return json.encode({ 'app': 'farolero', 'endpoint': _endpointId, 'sala': nombreSala, }); } }