import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import '../bloc/pendientes/pendientes_cubit.dart'; import '../bloc/app/app_cubit.dart'; import '../bloc/app/app_state.dart'; import '../../core/utils/hash_utils.dart'; import '../../core/utils/retry_utils.dart'; class PendientesPage extends StatelessWidget { const PendientesPage({super.key}); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { if (state.isLoading) { return const Center(child: CircularProgressIndicator()); } return Scaffold( body: Column( children: [ if (state.queueFull) Container( width: double.infinity, color: Theme.of(context).colorScheme.errorContainer, padding: const EdgeInsets.all(16), child: Row( children: [ Icon(Icons.warning, color: Theme.of(context).colorScheme.error), const SizedBox(width: 12), Expanded( child: Text( 'Cola llena (20/20). Libera espacio para continuar.', style: TextStyle( color: Theme.of(context).colorScheme.error, ), ), ), ], ), ), Expanded( child: state.pendientes.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.check_circle_outline, size: 64, color: Colors.green.shade400), const SizedBox(height: 16), Text( 'Sin pendientes', style: TextStyle(color: Colors.grey.shade600), ), ], ), ) : RefreshIndicator( onRefresh: () => context.read().load(), child: ListView.builder( padding: const EdgeInsets.all(16), itemCount: state.pendientes.length, itemBuilder: (context, index) { final pendiente = state.pendientes[index]; final dateFormat = DateFormat('HH:mm dd/MM'); return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( pendiente.puedeReintentar ? Icons.schedule : Icons.error, color: pendiente.puedeReintentar ? Colors.orange : Colors.red, ), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( pendiente.titulo ?? 'Sin título', style: const TextStyle( fontWeight: FontWeight.bold), ), Text( HashUtils.truncateHash( pendiente.hash), style: TextStyle( fontFamily: 'monospace', fontSize: 12, color: Colors.grey.shade600, ), ), ], ), ), ], ), const SizedBox(height: 12), Row( children: [ _InfoChip( icon: Icons.repeat, label: '${pendiente.intentos}/20', ), const SizedBox(width: 8), if (pendiente.ultimoIntento != null) _InfoChip( icon: Icons.access_time, label: dateFormat .format(pendiente.ultimoIntento!), ), const SizedBox(width: 8), if (pendiente.proximoIntento != null) _InfoChip( icon: Icons.timer, label: RetryUtils.formatTimeRemaining( pendiente.proximoIntento!), ), ], ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton.icon( onPressed: () => context .read() .eliminar(pendiente.hash), icon: const Icon(Icons.download), label: const Text('Recuperar'), ), const SizedBox(width: 8), BlocBuilder( builder: (context, appState) { return FilledButton.icon( onPressed: pendiente.puedeReintentar && appState.destinoActivo != null ? () => context .read() .reintentar( pendiente, appState.destinoActivo!, ) : null, icon: const Icon(Icons.replay), label: const Text('Reintentar'), ); }, ), ], ), ], ), ), ); }, ), ), ), ], ), floatingActionButton: state.pendientes.isNotEmpty ? BlocBuilder( builder: (context, appState) { return FloatingActionButton.extended( onPressed: appState.destinoActivo != null ? () => context .read() .reintentarTodos(appState.destinoActivo!) : null, icon: const Icon(Icons.replay), label: const Text('Reintentar todos'), ); }, ) : null, ); }, ); } } class _InfoChip extends StatelessWidget { final IconData icon; final String label; const _InfoChip({required this.icon, required this.label}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 14, color: Colors.grey.shade600), const SizedBox(width: 4), Text( label, style: TextStyle(fontSize: 12, color: Colors.grey.shade600), ), ], ), ); } }