import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../estado/estado_alarmas.dart'; import '../modelos/alarma_musical.dart'; import '../widgets/pluri_glass_surface.dart'; import '../widgets/pluri_icon.dart'; import '../widgets/pluri_premium_widgets.dart'; class PantallaAlarmas extends StatelessWidget { const PantallaAlarmas({super.key}); @override Widget build(BuildContext context) { final estado = context.watch(); return ListView( padding: const EdgeInsets.fromLTRB(0, 0, 0, 124), children: [ PluriScreenHeader( title: 'Alarmas musicales', subtitle: 'Despertador con radio, vacaciones, aviso previo y fallbacks seguros.', glyph: PluriIconGlyph.alarm, primaryActionLabel: 'Nueva alarma', onPrimaryAction: () => _crearDemo(context), trailing: PluriStatusPill( icon: Icons.alarm_on_rounded, label: '${estado.alarmas.length} alarmas', ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ _DiagnosticoAlarmas(estado: estado), const SizedBox(height: 12), if (estado.alarmas.isEmpty) const _EmptyAlarmas() else for (final alarma in estado.alarmas) ...[ _TarjetaAlarma(alarma: alarma), const SizedBox(height: 10), ], ], ), ), ], ); } Future _crearDemo(BuildContext context) async { final estado = context.read(); final ahora = TimeOfDay.now(); final alarma = estado.servicio.crearAlarma( nombre: 'Despertador musical', hora: ahora.hour, minuto: (ahora.minute + 2) % 60, tipoProgramacion: TipoProgramacionAlarma.diaria, diasSemana: const [], ); await estado.guardarAlarma(alarma); } } class _DiagnosticoAlarmas extends StatelessWidget { const _DiagnosticoAlarmas({required this.estado}); final EstadoAlarmas estado; @override Widget build(BuildContext context) { final diag = estado.diagnostico; return PluriGlassSurface( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.health_and_safety_outlined), const SizedBox(width: 12), Text( 'Fiabilidad Android', style: Theme.of(context).textTheme.titleMedium, ), const Spacer(), IconButton( tooltip: 'Revisar', icon: const Icon(Icons.refresh_rounded), onPressed: estado.cargarDiagnostico, ), ], ), const SizedBox(height: 8), _EstadoPermiso( label: 'Alarmas exactas', ok: diag?.puedeProgramarExactas ?? false, ), _EstadoPermiso( label: 'Notificaciones', ok: diag?.notificacionesPermitidas ?? false, ), if (diag == null) Text( 'Diagnóstico pendiente. En Android se revisan permisos nativos.', style: Theme.of(context).textTheme.bodySmall, ), ], ), ); } } class _EstadoPermiso extends StatelessWidget { const _EstadoPermiso({required this.label, required this.ok}); final String label; final bool ok; @override Widget build(BuildContext context) { return ListTile( dense: true, contentPadding: EdgeInsets.zero, leading: Icon( ok ? Icons.check_circle_rounded : Icons.warning_amber_rounded, color: ok ? Colors.greenAccent : Colors.orangeAccent, ), title: Text(label), subtitle: Text(ok ? 'Correcto' : 'Requiere revisión'), ); } } class _TarjetaAlarma extends StatelessWidget { const _TarjetaAlarma({required this.alarma}); final AlarmaMusical alarma; @override Widget build(BuildContext context) { final estado = context.read(); return PluriGlassSurface( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SwitchListTile.adaptive( contentPadding: EdgeInsets.zero, value: alarma.activa, onChanged: (value) => estado.cambiarActiva(alarma, value), title: Text( _hora(alarma), style: Theme.of(context).textTheme.headlineMedium, ), subtitle: Text(alarma.nombre), ), Wrap( spacing: 8, runSpacing: 8, children: [ Chip(label: Text(_programacion(alarma))), Chip(label: Text('Snooze ${alarma.snoozeMinutos} min')), Chip( label: Text( alarma.sonarEnVacaciones ? 'Suena en vacaciones' : 'Respeta vacaciones', ), ), ], ), if (alarma.proximaEjecucion != null) ...[ const SizedBox(height: 8), Text('Próxima: ${alarma.proximaEjecucion!.toLocal()}'), ], const SizedBox(height: 8), Row( children: [ TextButton.icon( icon: const Icon(Icons.skip_next_rounded), label: const Text('Saltar próxima'), onPressed: () => estado.saltarProxima(alarma.id), ), const Spacer(), IconButton( tooltip: 'Eliminar', icon: const Icon(Icons.delete_outline_rounded), onPressed: () => estado.eliminarAlarma(alarma.id), ), ], ), ], ), ); } String _hora(AlarmaMusical alarma) => '${alarma.hora.toString().padLeft(2, '0')}:${alarma.minuto.toString().padLeft(2, '0')}'; String _programacion(AlarmaMusical alarma) { return switch (alarma.tipoProgramacion) { TipoProgramacionAlarma.unica => 'Una vez', TipoProgramacionAlarma.diaria => 'Diaria', TipoProgramacionAlarma.diasSemana => 'Días: ${alarma.diasSemana.join(', ')}', }; } } class _EmptyAlarmas extends StatelessWidget { const _EmptyAlarmas(); @override Widget build(BuildContext context) { return const PluriGlassSurface( child: Column( children: [ Icon(Icons.alarm_add_rounded, size: 42), SizedBox(height: 12), Text('Todavía no hay alarmas.'), SizedBox(height: 4), Text('Crea una para empezar a diseñar tu despertar musical.'), ], ), ); } }