import 'package:flutter/material.dart'; import 'package:farolero/l10n/generated/app_localizations.dart'; import '../modelos/inicio_partida_multijugador.dart'; import '../modelos/snapshot_partida_online.dart'; import '../servicios/servicio_nearby.dart'; import '../tema/componentes_farolero.dart'; import '../tema/componentes_resultado_farolero.dart'; import '../tema/tema_app.dart'; import 'pantalla_debate_cliente.dart'; import 'pantalla_fin_partida_online.dart'; import 'pantalla_notas_online.dart'; import 'pantalla_revision_palabra.dart'; import 'pantalla_votacion_cliente.dart'; import 'package:provider/provider.dart'; class PantallaResultadoOnline extends StatefulWidget { final SnapshotPartidaOnline snapshot; final List jugadoresControlados; final String? pistaCategoria; const PantallaResultadoOnline({ super.key, required this.snapshot, required this.jugadoresControlados, this.pistaCategoria, }); @override State createState() => _PantallaResultadoOnlineState(); } class _PantallaResultadoOnlineState extends State { OnMensajeCallback? _listener; ServicioNearby? _nearby; late SnapshotPartidaOnline _snapshot; @override void initState() { super.initState(); _snapshot = widget.snapshot; _listener = (endpointId, mensaje) { if (!mounted) return; if (mensaje.tipo == TipoMensaje.partidaFin) { _abrirFin(mensaje.datos); return; } if (mensaje.tipo == TipoMensaje.votacionResultado) { setState(() => _snapshot = SnapshotPartidaOnline.fromJson(mensaje.datos)); return; } if (mensaje.tipo != TipoMensaje.fase) return; final fase = mensaje.datos['fase'] as String?; if (fase == 'debate') { _abrirDebate(mensaje.datos); } else if (fase == 'votacion') { _abrirVotacion(mensaje.datos); } else if (fase == 'adivinanza' || fase == 'resultado') { setState(() => _snapshot = SnapshotPartidaOnline.fromJson(mensaje.datos)); } else if (fase == 'finPartida') { _abrirFin(mensaje.datos); } }; WidgetsBinding.instance.addPostFrameCallback((_) { final listener = _listener; if (listener != null && mounted) { _nearby = context.read(); _nearby!.onMensaje(listener); } }); } @override void dispose() { final listener = _listener; if (listener != null) { _nearby?.removeMensajeListener(listener); } super.dispose(); } void _abrirDebate(Map datos) { final snapshot = SnapshotPartidaOnline.fromJson(datos); Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => PantallaDebateCliente( tiempoDebateSegundos: datos['tiempoDebateSegundos'] as int?, primerTurnoNombre: datos['primerTurnoNombre'] as String?, partidaId: snapshot.roomId, pistaCategoria: widget.pistaCategoria, jugadores: snapshot.jugadores, jugadoresControlados: widget.jugadoresControlados, onSolicitarVotacion: _solicitarVotacion, ), ), ); } void _abrirVotacion(Map datos) { final snapshot = SnapshotPartidaOnline.fromJson(datos); Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => PantallaVotacionCliente( jugadores: snapshot.jugadores, jugadoresControlados: widget.jugadoresControlados, partidaId: snapshot.roomId, pistaCategoria: widget.pistaCategoria, onVotos: _enviarVotos, ), ), ); } void _abrirFin(Map datos) { final snapshot = SnapshotPartidaOnline.fromJson(datos); Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => PantallaFinPartidaOnline( snapshot: snapshot, jugadoresControlados: widget.jugadoresControlados, pistaCategoria: widget.pistaCategoria, ), ), ); } void _solicitarVotacion() { final nearby = context.read(); if (nearby.hostEndpointId == null) return; nearby.enviarMensaje( nearby.hostEndpointId!, MensajeP2P( tipo: TipoMensaje.ping, datos: {'solicitoVotacion': true}, ), ); } void _enviarVotos(Map votos) { final nearby = context.read(); if (nearby.hostEndpointId == null) return; for (final entry in votos.entries) { nearby.enviarMensaje( nearby.hostEndpointId!, MensajeP2P( tipo: TipoMensaje.voto, datos: { 'votanteId': entry.key, 'votadoId': entry.value, 'votoporId': entry.value, }, ), ); } } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final resultado = _snapshot.resultadoActual; return Scaffold( backgroundColor: TemaApp.colorFondo, appBar: AppBar( title: Text(_snapshot.fase == 'adivinanza' ? l10n.impostorGuessTitle : l10n.result), automaticallyImplyLeading: false, backgroundColor: Colors.transparent, elevation: 0, actions: _acciones(context, l10n), ), body: FondoFarolero( intenso: true, child: SafeArea( top: false, child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: resultado == null ? _buildEsperaAdivinanza(context, l10n) : ResultadoRondaFarolero( resultado: resultado, jugadores: _snapshot.jugadores, mensaje: _snapshot.mensaje, ), ), ), ), ); } List _acciones(BuildContext context, AppLocalizations l10n) => [ IconButton( tooltip: l10n.seeYourWord, icon: const Icon(Icons.visibility), onPressed: widget.jugadoresControlados.isEmpty ? null : () => mostrarRevisionPalabraOnline( context: context, jugadoresControlados: widget.jugadoresControlados, pistaCategoria: widget.pistaCategoria, ), ), IconButton( tooltip: l10n.notesTitle, icon: const Icon(Icons.edit_note), onPressed: _snapshot.roomId == null || widget.jugadoresControlados.isEmpty ? null : () => Navigator.push( context, MaterialPageRoute( builder: (_) => PantallaNotasOnline( partidaId: _snapshot.roomId!, jugadores: _snapshot.jugadores, autoresControlados: widget.jugadoresControlados, ), ), ), ), ]; Widget _buildEsperaAdivinanza( BuildContext context, AppLocalizations l10n, ) { return Center( child: PanelFarolero( margin: const EdgeInsets.all(16), borderColor: TemaApp.colorNaranja.withValues(alpha: 0.48), child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, children: [ const ArteGameplayFarolero.resultado(height: 142), const SizedBox(height: 16), Text( _snapshot.mensaje ?? l10n.impostorCanGuess, textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 12), Text( l10n.waitingForHost, textAlign: TextAlign.center, style: TextStyle(color: TemaApp.colorTextoSecundario), ), ], ), ), ), ); } }