import 'package:flutter/material.dart'; import 'package:farolero/l10n/generated/app_localizations.dart'; import 'package:farolero/modelos/inicio_partida_multijugador.dart'; import 'package:farolero/modelos/jugador.dart'; import 'package:farolero/tema/tema_app.dart'; /// Pantalla de votación para cliente multidispositivo. /// Un cliente puede manejar uno o varios jugadores, por eso se recoge un voto /// por cada jugador controlado activo. class PantallaVotacionCliente extends StatefulWidget { final List jugadores; final List jugadoresControlados; final Function(Map votos) onVotos; const PantallaVotacionCliente({ super.key, required this.jugadores, this.jugadoresControlados = const [], required this.onVotos, }); @override State createState() => _PantallaVotacionClienteState(); } class _PantallaVotacionClienteState extends State { final Map _votosPorVotante = {}; List get _votantes => widget.jugadoresControlados; bool get _modoMultiVotante => _votantes.length > 1; bool get _votacionCompleta { if (_votantes.isEmpty) return _votosPorVotante.containsKey('_legacy'); return _votantes.every((votante) => _votosPorVotante[votante.jugadorId] != null); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; return Scaffold( backgroundColor: TemaApp.colorFondo, appBar: AppBar( title: Text(l10n.voting), automaticallyImplyLeading: false, backgroundColor: Colors.transparent, elevation: 0, ), body: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.whoDoYouThinkIsTheImpostor, style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 8), Text( _modoMultiVotante ? 'Emití un voto por cada jugador que manejás.' : l10n.selectOnePlayer, style: TextStyle(color: TemaApp.colorTextoSecundario), ), const SizedBox(height: 16), Expanded( child: _votantes.isEmpty ? _buildSelectorLegacy() : ListView.builder( itemCount: _votantes.length, itemBuilder: (context, index) { final votante = _votantes[index]; return _buildSelectorParaVotante(context, votante); }, ), ), const SizedBox(height: 16), SizedBox( width: double.infinity, height: 56, child: ElevatedButton.icon( onPressed: _votacionCompleta ? () => widget.onVotos(Map.unmodifiable(_votosPorVotante)) : null, icon: const Icon(Icons.how_to_vote), label: Text(l10n.votar), style: ElevatedButton.styleFrom( backgroundColor: TemaApp.colorAcento, foregroundColor: Colors.white, textStyle: const TextStyle(fontSize: 16), ), ), ), ], ), ), ); } Widget _buildSelectorLegacy() { return ListView.builder( itemCount: widget.jugadores.length, itemBuilder: (context, index) { final jugador = widget.jugadores[index]; final selected = _votosPorVotante['_legacy'] == jugador.id; return _buildJugadorVotable( jugador: jugador, index: index, selected: selected, onTap: () => setState(() => _votosPorVotante['_legacy'] = jugador.id), ); }, ); } Widget _buildSelectorParaVotante( BuildContext context, JugadorInicioPartida votante, ) { return Card( color: TemaApp.colorSuperficie, margin: const EdgeInsets.only(bottom: 16), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Voto de ${votante.nombre}', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), ...widget.jugadores.asMap().entries.map((entry) { final jugador = entry.value; final selected = _votosPorVotante[votante.jugadorId] == jugador.id; return _buildJugadorVotable( jugador: jugador, index: entry.key, selected: selected, onTap: () => setState( () => _votosPorVotante[votante.jugadorId] = jugador.id, ), ); }), ], ), ), ); } Widget _buildJugadorVotable({ required Jugador jugador, required int index, required bool selected, required VoidCallback onTap, }) { return Card( color: selected ? TemaApp.colorAcento.withValues(alpha: 0.3) : TemaApp.colorTarjeta, margin: const EdgeInsets.only(bottom: 8), child: ListTile( leading: CircleAvatar( backgroundColor: selected ? TemaApp.colorAcento : TemaApp.colorAcento.withValues(alpha: 0.3), child: Text( '${index + 1}', style: TextStyle( color: selected ? Colors.white : TemaApp.colorTexto, ), ), ), title: Text(jugador.nombre), trailing: selected ? const Icon(Icons.check_circle, color: TemaApp.colorAcento) : null, onTap: onTap, ), ); } }