import 'package:farolero/l10n/generated/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:provider/provider.dart'; import '../servicios/servicio_perfil_usuario.dart'; import '../tema/componentes_farolero.dart'; import '../tema/tema_app.dart'; import 'pantalla_ajustes.dart'; import 'pantalla_historial.dart'; import 'pantalla_reglas.dart'; import 'pantalla_seleccion_modo_juego.dart'; import 'pantalla_unirse.dart'; class PantallaPrincipal extends StatelessWidget { const PantallaPrincipal({super.key}); @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final servicioPerfil = context.watch(); final perfil = servicioPerfil.perfil; final gamificacion = servicioPerfil.resumenGamificacion; return Scaffold( extendBodyBehindAppBar: true, backgroundColor: const Color(0xFF05070D), body: FondoFarolero( intenso: true, child: Stack( children: [ Positioned.fill( child: Image.asset( 'assets/ui/generated/main/main_atmosphere_bg.png', fit: BoxFit.cover, alignment: Alignment.center, ), ), Positioned.fill( child: IgnorePointer( child: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( colors: [ Colors.black.withValues(alpha: 0.05), Colors.transparent, Colors.black.withValues(alpha: 0.58), ], stops: const [0.0, 0.48, 1.0], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), ), ), ), SafeArea( child: LayoutBuilder( builder: (context, constraints) { final isWide = constraints.maxWidth >= 700; final maxContentWidth = isWide ? 540.0 : 430.0; final horizontalPadding = isWide ? 32.0 : 20.0; return Center( child: SingleChildScrollView( padding: EdgeInsets.fromLTRB( horizontalPadding, 18, horizontalPadding, 24, ), child: ConstrainedBox( constraints: BoxConstraints(maxWidth: maxContentWidth), child: Column( children: [ _PerfilInicioPremium( nombre: perfil.nombre, nick: perfil.nick, avatarAsset: perfil.avatarAsset, fuego: gamificacion.fuego, medallas: gamificacion.medallas, onAjustes: () { Navigator.push( context, MaterialPageRoute( builder: (_) => const PantallaAjustes(), ), ); }, ajustesTooltip: l10n.settings, ).animate().fadeIn(duration: 280.ms).slideY(begin: -0.12), SizedBox(height: isWide ? 48 : 34), _HeroInicioPremium( subtitulo: l10n.subtitle, tagline: l10n.mainTagline, compact: constraints.maxHeight < 760, ) .animate() .fadeIn(delay: 120.ms, duration: 420.ms) .scale(begin: const Offset(0.92, 0.92)), SizedBox(height: isWide ? 46 : 34), _BotonInicioPremium.primario( texto: l10n.play, icono: Icons.play_arrow_rounded, onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (_) => const PantallaSeleccionModoJuego(), ), ); }, ).animate().fadeIn(delay: 240.ms).slideY(begin: 0.16), const SizedBox(height: 14), _BotonInicioPremium.secundario( texto: l10n.joinGame, icono: Icons.bolt_rounded, onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const PantallaUnirse()), ); }, ).animate().fadeIn(delay: 320.ms).slideY(begin: 0.16), const SizedBox(height: 12), _BotonInicioPremium.oscuro( texto: l10n.howToPlay, icono: Icons.question_mark_rounded, onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const PantallaReglas()), ); }, ).animate().fadeIn(delay: 390.ms).slideY(begin: 0.16), const SizedBox(height: 14), _AccesoHistorialPremium( etiqueta: l10n.history, onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const PantallaHistorial()), ); }, ).animate().fadeIn(delay: 470.ms).slideY(begin: 0.14), const SizedBox(height: 28), Text( l10n.playersRange, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: TemaApp.colorTextoSecundario.withValues(alpha: 0.82), letterSpacing: 0.8, ), ), ], ), ), ), ); }, ), ), ], ), ), ); } } class _PerfilInicioPremium extends StatelessWidget { final String nombre; final String nick; final String? avatarAsset; final int fuego; final List medallas; final VoidCallback onAjustes; final String ajustesTooltip; const _PerfilInicioPremium({ required this.nombre, required this.nick, required this.avatarAsset, required this.fuego, required this.medallas, required this.onAjustes, required this.ajustesTooltip, }); @override Widget build(BuildContext context) { final progreso = (fuego / 100).clamp(0.0, 1.0).toDouble(); return Container( padding: const EdgeInsets.fromLTRB(14, 12, 10, 12), decoration: _decoracionCristal(radius: 28, alpha: 0.82), child: Row( children: [ AvatarFarolero( texto: nombre.substring(0, 1).toUpperCase(), assetPath: avatarAsset, size: 58, fuego: fuego, medallas: medallas, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( nombre, maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.titleMedium?.copyWith( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w900, ), ), Text( '@$nick', maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: TemaApp.colorTextoSecundario, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 8), ClipRRect( borderRadius: BorderRadius.circular(999), child: Stack( children: [ Container(height: 8, color: Colors.black.withValues(alpha: 0.55)), FractionallySizedBox( widthFactor: progreso, child: Container( height: 8, decoration: const BoxDecoration( gradient: LinearGradient( colors: [ Color(0xFFE53935), TemaApp.colorNaranja, TemaApp.colorDorado, ], ), ), ), ), ], ), ), ], ), ), const SizedBox(width: 10), IconButton.filledTonal( tooltip: ajustesTooltip, onPressed: onAjustes, style: IconButton.styleFrom( backgroundColor: TemaApp.colorDorado.withValues(alpha: 0.14), foregroundColor: TemaApp.colorDorado, side: BorderSide(color: TemaApp.colorDorado.withValues(alpha: 0.44)), ), icon: const Icon(Icons.settings_rounded), ), ], ), ); } } class _HeroInicioPremium extends StatelessWidget { final String subtitulo; final String tagline; final bool compact; const _HeroInicioPremium({ required this.subtitulo, required this.tagline, required this.compact, }); @override Widget build(BuildContext context) { final heroSize = compact ? 148.0 : 188.0; return SizedBox( height: compact ? 260 : 320, child: Stack( alignment: Alignment.center, children: [ Positioned.fill( child: Image.asset( 'assets/ui/premium/lantern_radial_glow.png', fit: BoxFit.contain, opacity: const AlwaysStoppedAnimation(0.48), ), ), Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset( 'assets/ui/generated/main/main_lantern_hero.png', width: heroSize, height: heroSize, fit: BoxFit.contain, ).animate(onPlay: (controller) => controller.repeat(reverse: true)).scale( begin: const Offset(0.985, 0.985), end: const Offset(1.035, 1.035), duration: 1800.ms, curve: Curves.easeInOut, ), SizedBox(height: compact ? 8 : 12), LogoFarolero(size: compact ? 58 : 72), const SizedBox(height: 8), Text( subtitulo, textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleMedium?.copyWith( color: TemaApp.colorTexto, fontSize: 17, fontWeight: FontWeight.w800, shadows: [ Shadow( color: TemaApp.colorNaranja.withValues(alpha: 0.35), blurRadius: 14, ), ], ), ), const SizedBox(height: 4), Text( tagline, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: TemaApp.colorTextoSecundario, fontWeight: FontWeight.w600, ), ), ], ), ], ), ); } } class _BotonInicioPremium extends StatelessWidget { final String texto; final IconData icono; final VoidCallback onPressed; final LinearGradient gradient; final Color foreground; final double height; final bool hero; const _BotonInicioPremium._({ required this.texto, required this.icono, required this.onPressed, required this.gradient, required this.foreground, required this.height, required this.hero, }); factory _BotonInicioPremium.primario({ required String texto, required IconData icono, required VoidCallback onPressed, }) { return _BotonInicioPremium._( texto: texto, icono: icono, onPressed: onPressed, gradient: const LinearGradient( colors: [Color(0xFFFFE28A), TemaApp.colorDorado, TemaApp.colorNaranja], begin: Alignment.topLeft, end: Alignment.bottomRight, ), foreground: const Color(0xFF1C0D03), height: 72, hero: true, ); } factory _BotonInicioPremium.secundario({ required String texto, required IconData icono, required VoidCallback onPressed, }) { return _BotonInicioPremium._( texto: texto, icono: icono, onPressed: onPressed, gradient: const LinearGradient( colors: [Color(0xFF211730), Color(0xFF121B28)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), foreground: Colors.white, height: 60, hero: false, ); } factory _BotonInicioPremium.oscuro({ required String texto, required IconData icono, required VoidCallback onPressed, }) { return _BotonInicioPremium._( texto: texto, icono: icono, onPressed: onPressed, gradient: const LinearGradient( colors: [Color(0xFF101A24), Color(0xFF080D13)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), foreground: TemaApp.colorTexto, height: 60, hero: false, ); } @override Widget build(BuildContext context) { final radius = BorderRadius.circular(hero ? 26 : 22); return Material( color: Colors.transparent, child: InkWell( borderRadius: radius, onTap: onPressed, child: Ink( height: height, decoration: BoxDecoration( gradient: gradient, borderRadius: BorderRadius.circular(hero ? 26 : 22), border: Border.all( color: hero ? const Color(0xFFFFF0B8) : TemaApp.colorDorado.withValues(alpha: 0.34), ), boxShadow: [ BoxShadow( color: (hero ? TemaApp.colorNaranja : Colors.black).withValues(alpha: hero ? 0.46 : 0.42), blurRadius: hero ? 34 : 18, offset: const Offset(0, 12), ), ], ), child: ClipRRect( borderRadius: radius, child: Stack( alignment: Alignment.center, children: [ Positioned.fill( child: Image.asset( 'assets/ui/premium/card_sheen_overlay.png', fit: BoxFit.cover, opacity: AlwaysStoppedAnimation(hero ? 0.20 : 0.14), ), ), Padding( padding: EdgeInsets.symmetric( horizontal: hero ? 18 : 16, vertical: hero ? 14 : 11, ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: hero ? 46 : 38, child: Icon( icono, color: foreground, size: hero ? 36 : 27, ), ), const SizedBox(width: 10), Expanded( child: Center( child: FittedBox( fit: BoxFit.scaleDown, child: Text( texto.toUpperCase(), maxLines: 1, textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleLarge?.copyWith( color: foreground, fontSize: hero ? 28 : 18, fontWeight: FontWeight.w900, letterSpacing: hero ? 1.4 : 1.0, ), ), ), ), ), SizedBox(width: hero ? 56 : 48), ], ), ), ], ), ), ), ), ); } } class _AccesoHistorialPremium extends StatelessWidget { final String etiqueta; final VoidCallback onPressed; const _AccesoHistorialPremium({required this.etiqueta, required this.onPressed}); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(22), onTap: onPressed, child: Ink( height: 58, decoration: _decoracionCristal(radius: 22, alpha: 0.72), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.history_rounded, color: TemaApp.colorNaranja), const SizedBox(width: 10), Text( etiqueta.toUpperCase(), style: Theme.of(context).textTheme.titleMedium?.copyWith( color: TemaApp.colorDorado, fontWeight: FontWeight.w900, letterSpacing: 1.2, ), ), ], ), ), ), ); } } BoxDecoration _decoracionCristal({required double radius, required double alpha}) { return BoxDecoration( gradient: LinearGradient( colors: [ const Color(0xFF111C29).withValues(alpha: alpha), const Color(0xFF160C1F).withValues(alpha: alpha - 0.08), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(radius), border: Border.all(color: TemaApp.colorDorado.withValues(alpha: 0.42)), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.46), blurRadius: 24, offset: const Offset(0, 12), ), BoxShadow( color: TemaApp.colorNaranja.withValues(alpha: 0.14), blurRadius: 26, ), ], ); }