import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../estado/estado_radio.dart'; import '../l10n/gen/app_localizations.dart'; import '../modelos/emisora.dart'; import '../modelos/grupo_favoritos.dart'; import '../widgets/pluri_glass_surface.dart'; import '../widgets/pluri_icon.dart'; import '../widgets/pluri_layout.dart'; import '../widgets/pluri_premium_widgets.dart'; import 'package:pluriwave/widgets/tarjeta_emisora.dart'; import 'reproducir_minimizado.dart'; class PantallaFavoritos extends StatelessWidget { const PantallaFavoritos({super.key}); @override Widget build(BuildContext context) { final estado = context.watch(); final favoritos = estado.listaFavoritos; final grupos = estado.gruposFavoritos; final l10n = AppLocalizations.of(context); if (favoritos.isEmpty) { return ListView( padding: PluriLayout.pageListPadding, children: [ PluriScreenHeader( title: l10n.favoritesTitle, subtitle: l10n.favoritesHeaderSubtitle, glyph: PluriIconGlyph.favorites, trailing: PluriStatusPill( icon: Icons.favorite_rounded, label: l10n.favoritesCollection, ), ), SizedBox( height: 320, child: PluriEmptyState( glyph: PluriIconGlyph.favorites, title: l10n.favoritesEmptyTitle, subtitle: l10n.favoritesEmptySubtitle, ), ), ], ); } final gruposVisibles = grupos.isEmpty ? const [ GrupoFavoritos( id: GrupoFavoritos.sinAsignarId, nombre: 'Sin asignar', orden: 0, protegido: true, ), ] : grupos; return CustomScrollView( slivers: [ SliverToBoxAdapter( child: PluriScreenHeader( title: l10n.favoritesTitle, subtitle: l10n.favoritesHeaderSubtitle, glyph: PluriIconGlyph.favorites, trailing: PluriStatusPill( icon: Icons.library_music_rounded, label: l10n.favoritesSavedCount(favoritos.length), ), ), ), SliverPadding( padding: const EdgeInsets.fromLTRB( PluriLayout.horizontal, 4, PluriLayout.horizontal, PluriLayout.bottomChromeInset, ), sliver: SliverList( delegate: SliverChildListDelegate([ for (final grupo in gruposVisibles) ...[ _GrupoFavoritosPanel( grupo: grupo, grupos: gruposVisibles, emisoras: favoritos .where((e) => e.grupoFavoritosId == grupo.id) .toList(), ), const SizedBox(height: 12), ], ]), ), ), ], ); } } class _GrupoFavoritosPanel extends StatelessWidget { const _GrupoFavoritosPanel({ required this.grupo, required this.grupos, required this.emisoras, }); final GrupoFavoritos grupo; final List grupos; final List emisoras; String _nombreVisible(AppLocalizations l10n, GrupoFavoritos grupo) => grupo.esSinAsignar ? l10n.favoriteGroupsUnassigned : grupo.nombre; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); final theme = Theme.of(context); return PluriGlassSurface( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(grupo.esSinAsignar ? Icons.lock_rounded : Icons.folder_rounded), const SizedBox(width: 8), Expanded( child: Text( _nombreVisible(l10n, grupo), style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w900, ), ), ), Text('${emisoras.length}'), ], ), const SizedBox(height: 8), if (emisoras.isEmpty) Padding( padding: const EdgeInsets.only(bottom: 4), child: Text( l10n.favoritesEmptyTitle, style: theme.textTheme.bodySmall, ), ) else for (var i = 0; i < emisoras.length; i++) ...[ _FavoritoItem( emisora: emisoras[i], grupos: grupos, grupoActual: grupo, ), if (i < emisoras.length - 1) const SizedBox(height: 8), ], ], ), ); } } class _FavoritoItem extends StatelessWidget { const _FavoritoItem({ required this.emisora, required this.grupos, required this.grupoActual, }); final Emisora emisora; final List grupos; final GrupoFavoritos grupoActual; String _nombreVisible(AppLocalizations l10n, GrupoFavoritos grupo) => grupo.esSinAsignar ? l10n.favoriteGroupsUnassigned : grupo.nombre; Future _asignar(BuildContext context) async { final l10n = AppLocalizations.of(context); final seleccionado = await showModalBottomSheet( context: context, showDragHandle: true, builder: (ctx) => SafeArea( child: ListView( shrinkWrap: true, children: [ Padding( padding: const EdgeInsets.fromLTRB(20, 4, 20, 12), child: Text( l10n.favoriteGroupsAssign, style: Theme.of(ctx).textTheme.titleLarge, ), ), for (final grupo in grupos) ListTile( leading: Icon( grupo.id == emisora.grupoFavoritosId ? Icons.radio_button_checked_rounded : Icons.radio_button_off_rounded, ), title: Text(_nombreVisible(l10n, grupo)), onTap: () => Navigator.pop(ctx, grupo.id), ), ], ), ), ); if (seleccionado == null || !context.mounted) return; await context.read().asignarGrupoFavorito( emisora.uuid, seleccionado, ); if (!context.mounted) return; final destino = grupos.firstWhere((g) => g.id == seleccionado); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( l10n.favoriteGroupsAssigned(emisora.nombre, _nombreVisible(l10n, destino)), ), ), ); } Future _eliminar(BuildContext context) async { final l10n = AppLocalizations.of(context); final estado = context.read(); await estado.favoritos.eliminar(emisora.uuid); await estado.cargarFavoritos(); if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(l10n.favoritesRemovedMessage(emisora.nombre))), ); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); return Row( children: [ Expanded( child: TarjetaEmisora( key: Key(emisora.uuid), emisora: emisora, esCompacta: true, onTap: () => reproducirMinimizado(context, emisora), ), ), const SizedBox(width: 6), Column( mainAxisSize: MainAxisSize.min, children: [ IconButton.filledTonal( tooltip: l10n.favoriteGroupsAssignSubtitle( _nombreVisible(l10n, grupoActual), ), icon: const Icon(Icons.drive_file_move_rounded), onPressed: () => _asignar(context), ), IconButton.filledTonal( tooltip: l10n.favoritesRemoveTooltip, icon: const Icon(Icons.delete_outline_rounded), onPressed: () => _eliminar(context), ), ], ), ], ); } }