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/servicios/servicio_notas.dart'; import 'package:farolero/tema/tema_app.dart'; class PantallaNotasOnline extends StatefulWidget { final String partidaId; final List jugadores; final List autoresControlados; const PantallaNotasOnline({ super.key, required this.partidaId, required this.jugadores, required this.autoresControlados, }); @override State createState() => _PantallaNotasOnlineState(); } class _PantallaNotasOnlineState extends State { JugadorInicioPartida? _autor; final Map _controladores = {}; final TextEditingController _notaLibreController = TextEditingController(); bool _cargando = false; List get _jugadoresActivos => widget.jugadores.where((jugador) => !jugador.eliminado).toList(); @override void initState() { super.initState(); for (final jugador in _jugadoresActivos) { _controladores[jugador.id] = TextEditingController(); } if (widget.autoresControlados.length == 1) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) _seleccionarAutor(widget.autoresControlados.first); }); } } @override void dispose() { for (final controller in _controladores.values) { controller.dispose(); } _notaLibreController.dispose(); super.dispose(); } Future _seleccionarAutor(JugadorInicioPartida autor) async { setState(() { _autor = autor; _cargando = true; for (final controller in _controladores.values) { controller.clear(); } _notaLibreController.clear(); }); final datos = await ServicioNotas.cargarNotasPartida( partidaId: widget.partidaId, autorJugadorId: autor.jugadorId, ); if (!mounted) return; final notas = datos['notas'] as Map; for (final entry in notas.entries) { _controladores[entry.key]?.text = entry.value; } _notaLibreController.text = datos['notaLibre'] as String; setState(() => _cargando = false); } Future _guardarNotas() async { final autor = _autor; if (autor == null) return; final notas = {}; for (final entry in _controladores.entries) { final texto = entry.value.text.trim(); if (texto.isNotEmpty) notas[entry.key] = texto; } await ServicioNotas.guardarNotasPartida( partidaId: widget.partidaId, autorJugadorId: autor.jugadorId, notasPorJugador: notas, notaLibre: _notaLibreController.text, ); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; return PopScope( canPop: true, onPopInvokedWithResult: (didPop, result) => _guardarNotas(), child: Scaffold( appBar: AppBar( title: Text(l10n.notesTitle), actions: [ if (_autor != null) IconButton( icon: const Icon(Icons.save), onPressed: () async { await _guardarNotas(); if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(l10n.notesSaved)), ); }, ), ], ), body: _autor == null ? _buildSelector(context) : _buildNotas(context), ), ); } Widget _buildSelector(BuildContext context) { return Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( AppLocalizations.of(context)!.whoAreYou, style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 16), Expanded( child: ListView( children: widget.autoresControlados .map( (autor) => Card( child: ListTile( leading: const Icon(Icons.edit_note), title: Text(autor.nombre), onTap: () => _seleccionarAutor(autor), ), ), ) .toList(), ), ), ], ), ); } Widget _buildNotas(BuildContext context) { if (_cargando) return const Center(child: CircularProgressIndicator()); final l10n = AppLocalizations.of(context)!; final autor = _autor!; return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ if (widget.autoresControlados.length > 1) IconButton( icon: const Icon(Icons.arrow_back), onPressed: () async { await _guardarNotas(); if (!mounted) return; setState(() => _autor = null); }, ), Expanded( child: Text( l10n.notesOf(autor.nombre), style: Theme.of(context).textTheme.titleLarge, ), ), ], ), const SizedBox(height: 16), Text( l10n.notesAboutPlayers, style: Theme.of(context).textTheme.titleMedium?.copyWith( color: TemaApp.colorTextoSecundario, ), ), const SizedBox(height: 8), ..._jugadoresActivos .where((jugador) => jugador.id != autor.jugadorId) .map( (jugador) => Padding( padding: const EdgeInsets.only(bottom: 8), child: TextField( controller: _controladores[jugador.id], decoration: InputDecoration( labelText: jugador.nombre, prefixIcon: const Icon(Icons.person, size: 20), hintText: l10n.playerNoteHint, ), maxLines: 2, minLines: 1, ), ), ), const SizedBox(height: 16), Text( l10n.freeNote, style: Theme.of(context).textTheme.titleMedium?.copyWith( color: TemaApp.colorTextoSecundario, ), ), const SizedBox(height: 8), TextField( controller: _notaLibreController, decoration: InputDecoration( hintText: l10n.freeNoteHint, prefixIcon: const Icon(Icons.note, size: 20), ), maxLines: 5, minLines: 3, ), ], ), ); } }