import 'package:flutter/material.dart'; import 'package:farolero/l10n/generated/app_localizations.dart'; import 'package:provider/provider.dart'; import '../servicios/servicio_idioma.dart'; import '../servicios/servicio_perfil_usuario.dart'; import '../tema/componentes_farolero.dart'; import '../tema/tema_app.dart'; class PantallaAjustes extends StatefulWidget { const PantallaAjustes({super.key}); @override State createState() => _PantallaAjustesState(); } class _PantallaAjustesState extends State { double _volumen = 0.7; bool _vibracion = true; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final servicioIdioma = context.watch(); final perfil = context.watch().perfil; return Scaffold( appBar: AppBar(title: Text(l10n.settingsTitle)), body: FondoFarolero( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Card( child: ListTile( leading: AvatarFarolero( texto: perfil.nombre.substring(0, 1).toUpperCase(), assetPath: perfil.avatarAsset, size: 48, ), title: Text(perfil.nombre), subtitle: Text('@${perfil.nick}'), trailing: const Icon(Icons.edit), onTap: () => _editarPerfil(context), ), ), const SizedBox(height: 12), // Selector de idioma Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(l10n.language, style: Theme.of(context).textTheme.titleLarge), const SizedBox(height: 12), // Opción automática (sistema) _opcionIdioma( context, bandera: '🌐', nombre: 'Auto (${_nombreIdiomaDelSistema()})', codigo: 'sistema', seleccionado: servicioIdioma.codigoActual == 'sistema', onTap: () => servicioIdioma.cambiarIdioma('sistema'), ), const Divider(height: 1), // Lista de idiomas ...ServicioIdioma.idiomasSoportados.entries.map((entrada) { return _opcionIdioma( context, bandera: entrada.value.bandera, nombre: entrada.value.nombre, codigo: entrada.key, seleccionado: servicioIdioma.codigoActual == entrada.key, onTap: () => servicioIdioma.cambiarIdioma(entrada.key), ); }), ], ), ), ), const SizedBox(height: 12), // Volumen de efectos de sonido Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(l10n.soundVolume, style: Theme.of(context).textTheme.titleLarge), const SizedBox(height: 8), Slider( value: _volumen, onChanged: (v) => setState(() => _volumen = v), activeColor: TemaApp.colorAcento, inactiveColor: TemaApp.colorTarjeta, ), ], ), ), ), const SizedBox(height: 12), // Vibración Card( child: SwitchListTile( title: Text(l10n.vibration), value: _vibracion, onChanged: (v) => setState(() => _vibracion = v), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), ), ), const SizedBox(height: 12), // Acerca de Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(l10n.about, style: Theme.of(context).textTheme.titleLarge), const SizedBox(height: 12), _filaInfo(context, l10n.version, '1.0.0'), const SizedBox(height: 8), _filaInfo(context, l10n.developer, 'FreeTTimeLab'), const SizedBox(height: 8), SizedBox( width: double.infinity, child: OutlinedButton( onPressed: () { showLicensePage( context: context, applicationName: 'Farolero', applicationVersion: '1.0.0', ); }, child: Text(l10n.licenses), ), ), ], ), ), ), const SizedBox(height: 16), ], ), ), ), ); } Widget _opcionIdioma( BuildContext context, { required String bandera, required String nombre, required String codigo, required bool seleccionado, required VoidCallback onTap, }) { return ListTile( leading: Text(bandera, style: const TextStyle(fontSize: 24)), title: Text(nombre), trailing: seleccionado ? const Icon(Icons.check_circle, color: TemaApp.colorAcento) : null, onTap: onTap, dense: true, selected: seleccionado, selectedTileColor: TemaApp.colorAcento.withValues(alpha: 0.1), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ); } Widget _filaInfo(BuildContext context, String etiqueta, String valor) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(etiqueta, style: Theme.of(context).textTheme.bodyMedium), Text(valor, style: Theme.of(context).textTheme.bodyLarge), ], ); } Future _editarPerfil(BuildContext context) async { final servicioPerfil = context.read(); final actual = servicioPerfil.perfil; final nombreController = TextEditingController(text: actual.nombre); final nickController = TextEditingController(text: actual.nick); var avatarSeleccionado = actual.avatarAsset; await showDialog( context: context, builder: (ctx) => StatefulBuilder( builder: (ctx, setDialogState) => AlertDialog( title: const Text('Perfil del dispositivo'), content: SizedBox( width: 420, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: nombreController, textCapitalization: TextCapitalization.words, decoration: const InputDecoration( labelText: 'Nombre', prefixIcon: Icon(Icons.person), ), ), const SizedBox(height: 12), TextField( controller: nickController, decoration: const InputDecoration( labelText: 'Nick', prefixIcon: Icon(Icons.alternate_email), ), ), const SizedBox(height: 16), GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 5, mainAxisSpacing: 8, crossAxisSpacing: 8, ), itemCount: ServicioPerfilUsuario.avatares.length, itemBuilder: (context, index) { final avatar = ServicioPerfilUsuario.avatares[index]; final seleccionado = avatar == avatarSeleccionado; return InkWell( borderRadius: BorderRadius.circular(999), onTap: () => setDialogState( () => avatarSeleccionado = avatar, ), child: Container( decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: seleccionado ? TemaApp.colorNaranja : Colors.transparent, width: 3, ), ), child: AvatarFarolero( texto: '', assetPath: avatar, size: 48, ), ), ); }, ), ], ), ), ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Cancelar'), ), TextButton( onPressed: () async { await servicioPerfil.guardar( nombre: nombreController.text, nick: nickController.text, avatarAsset: avatarSeleccionado, ); if (ctx.mounted) Navigator.pop(ctx); }, child: const Text('Guardar'), ), ], ), ), ); nombreController.dispose(); nickController.dispose(); } String _nombreIdiomaDelSistema() { final locale = WidgetsBinding.instance.platformDispatcher.locale; final codigo = locale.countryCode != null && locale.countryCode!.isNotEmpty ? '${locale.languageCode}_${locale.countryCode}' : locale.languageCode; final info = ServicioIdioma.idiomasSoportados[codigo] ?? ServicioIdioma.idiomasSoportados[locale.languageCode]; return info?.nombre ?? locale.languageCode; } }