import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../estado/estado_alarmas.dart';
import '../estado/estado_radio.dart';
import '../modelos/alarma_musical.dart';
import '../modelos/emisora.dart';
import '../widgets/pluri_glass_surface.dart';
import '../widgets/pluri_icon.dart';
import '../widgets/pluri_layout.dart';
import '../widgets/pluri_premium_widgets.dart';

class PantallaAlarmas extends StatelessWidget {
  const PantallaAlarmas({super.key});

  @override
  Widget build(BuildContext context) {
    final estado = context.watch<EstadoAlarmas>();

    return RefreshIndicator(
      onRefresh: estado.refrescarProgramacion,
      child: ListView(
        padding: PluriLayout.pageListPadding,
        children: [
          PluriScreenHeader(
            title: 'Despertar musical',
            subtitle:
                'Alarmas con radio, sonido seguro, vacaciones inteligentes y próxima ejecución siempre visible.',
            glyph: PluriIconGlyph.alarm,
            primaryActionLabel: 'Crear alarma',
            onPrimaryAction: () => _abrirEditor(context),
            trailing: PluriStatusPill(
              icon: Icons.alarm_on_rounded,
              label: '${estado.alarmas.length} alarmas',
            ),
          ),
          Padding(
            padding: PluriLayout.pageContentPadding,
            child: Column(
              children: [
                _PanelProximaAlarma(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: 12),
                  ],
                _PanelVacaciones(estado: estado),
                const SizedBox(height: 12),
                _AccesoDiagnostico(estado: estado),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _abrirEditor(BuildContext context, {AlarmaMusical? alarma}) async {
    await showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      useSafeArea: true,
      backgroundColor: Colors.transparent,
      builder: (_) => _EditorAlarmaSheet(alarma: alarma),
    );
  }
}

class _PanelProximaAlarma extends StatelessWidget {
  const _PanelProximaAlarma({required this.estado});

  final EstadoAlarmas estado;

  @override
  Widget build(BuildContext context) {
    final proxima = estado.proximaAlarma;
    return PluriGlassSurface(
      glowColor: const Color(0xFFFFB86B).withValues(alpha: 0.28),
      child: Row(
        children: [
          const _AssetIcon('assets/icons/alarmas/alarm_music.png', size: 72),
          const SizedBox(width: 14),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  proxima == null ? 'Sin alarmas activas' : 'Próxima alarma',
                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
                    fontWeight: FontWeight.w900,
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  proxima == null
                      ? 'Creá una alarma y PluriWave calculará la siguiente ejecución automáticamente.'
                      : '${proxima.nombre} · ${_fechaHora(proxima.proximaEjecucion!)}',
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _TarjetaAlarma extends StatelessWidget {
  const _TarjetaAlarma({required this.alarma});

  final AlarmaMusical alarma;

  @override
  Widget build(BuildContext context) {
    final estado = context.watch<EstadoAlarmas>();
    final excepcion = estado.ultimaExcepcionPara(alarma.id);
    final mensajeVacaciones = _mensajeVacaciones(estado.vacaciones);
    return PluriGlassSurface(
      glowColor: const Color(0xFF22D3EE).withValues(alpha: 0.22),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              const _AssetIcon('assets/icons/alarmas/alarm_music.png', size: 64),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      _hora(alarma),
                      style: Theme.of(context).textTheme.headlineMedium?.copyWith(
                        fontWeight: FontWeight.w900,
                        letterSpacing: -1,
                      ),
                    ),
                    Text(alarma.nombre),
                  ],
                ),
              ),
              Switch.adaptive(
                value: alarma.activa,
                onChanged: (value) => estado.cambiarActiva(alarma, value),
              ),
            ],
          ),
          const SizedBox(height: 12),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              _InfoChip(icon: Icons.repeat_rounded, label: _programacion(alarma)),
              _InfoChip(icon: Icons.snooze_rounded, label: '${alarma.snoozeMinutos} min'),
              _InfoChip(
                icon: Icons.beach_access_rounded,
                label: alarma.sonarEnVacaciones
                    ? 'Suena en vacaciones'
                    : 'Pausa en vacaciones',
              ),
              _InfoChip(
                icon: Icons.volume_up_rounded,
                label: '${(alarma.volumen * 100).round()}%',
              ),
            ],
          ),
          const SizedBox(height: 12),
          if (alarma.proximaEjecucion != null)
            _NoticeLine(
              icon: Icons.event_available_rounded,
              text: 'Siguiente ejecución: ${_fechaHora(alarma.proximaEjecucion!)}',
            )
          else
            const _NoticeLine(
              icon: Icons.pause_circle_outline_rounded,
              text: 'No tiene próxima ejecución activa.',
            ),
          if (excepcion != null) ...[
            const SizedBox(height: 6),
            _NoticeLine(
              icon: Icons.skip_next_rounded,
              text: 'Una ejecución fue omitida: ${_fechaHora(excepcion.ejecucion)}.',
            ),
          ],
          if (mensajeVacaciones != null) ...[
            const SizedBox(height: 6),
            _NoticeLine(
              icon: Icons.beach_access_rounded,
              text: mensajeVacaciones,
            ),
          ],
          const SizedBox(height: 12),
          Row(
            children: [
              TextButton.icon(
                icon: const Icon(Icons.edit_rounded),
                label: const Text('Editar'),
                onPressed: () => _abrirEditor(context, alarma: alarma),
              ),
              TextButton.icon(
                icon: const Icon(Icons.skip_next_rounded),
                label: const Text('Omitir siguiente'),
                onPressed: alarma.proximaEjecucion == null
                    ? null
                    : () async {
                        await estado.saltarProxima(alarma.id);
                        if (context.mounted) {
                          final alarmas =
                              context.read<EstadoAlarmas>().alarmas;
                          AlarmaMusical? actualizada;
                          for (final item in alarmas) {
                            if (item.id == alarma.id) {
                              actualizada = item;
                              break;
                            }
                          }
                          ScaffoldMessenger.of(context).showSnackBar(
                            SnackBar(
                              content: Text(
                                actualizada?.proximaEjecucion == null
                                    ? 'Alarma omitida. No queda próxima ejecución.'
                                    : 'Alarma omitida. Volverá el ${_fechaHora(actualizada!.proximaEjecucion!)}.',
                              ),
                            ),
                          );
                        }
                      },
              ),
              const Spacer(),
              IconButton(
                tooltip: 'Eliminar',
                icon: const Icon(Icons.delete_outline_rounded),
                onPressed: () => estado.eliminarAlarma(alarma.id),
              ),
            ],
          ),
        ],
      ),
    );
  }

  String? _mensajeVacaciones(List<RangoVacaciones> vacaciones) {
    if (alarma.sonarEnVacaciones) return null;
    final ahora = DateTime.now();
    RangoVacaciones? actual;
    for (final rango in vacaciones) {
      if (rango.contiene(ahora)) {
        actual = rango;
        break;
      }
    }
    if (actual != null) {
      if (alarma.proximaEjecucion == null) {
        return 'Está pausada por vacaciones (${actual.nombre}) y sin próxima ejecución.';
      }
      return 'Está pausada por vacaciones (${actual.nombre}) y vuelve el ${_fechaHora(alarma.proximaEjecucion!)}.';
    }
    if (alarma.proximaEjecucion != null) {
      return 'Con vacaciones activas, volverá a sonar el ${_fechaHora(alarma.proximaEjecucion!)}.';
    }
    return null;
  }

  void _abrirEditor(BuildContext context, {required AlarmaMusical alarma}) {
    showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      useSafeArea: true,
      backgroundColor: Colors.transparent,
      builder: (_) => _EditorAlarmaSheet(alarma: alarma),
    );
  }
}

class _EditorAlarmaSheet extends StatefulWidget {
  const _EditorAlarmaSheet({this.alarma});

  final AlarmaMusical? alarma;

  @override
  State<_EditorAlarmaSheet> createState() => _EditorAlarmaSheetState();
}

class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
  late final TextEditingController _nombreController;
  late TimeOfDay _hora;
  late DateTime _fecha;
  late TipoProgramacionAlarma _tipo;
  late Set<int> _diasSemana;
  late int _snooze;
  late double _volumen;
  late bool _sonarEnVacaciones;
  late SonidoInternoAlarma _sonidoInterno;
  Emisora? _emisora;
  bool _favoritosSolicitados = false;

  @override
  void initState() {
    super.initState();
    final alarma = widget.alarma;
    final ahora = DateTime.now().add(const Duration(minutes: 5));
    _nombreController = TextEditingController(
      text: alarma?.nombre ?? 'Despertador musical',
    );
    _hora = TimeOfDay(hour: alarma?.hora ?? ahora.hour, minute: alarma?.minuto ?? ahora.minute);
    _fecha = alarma?.fechaUnica ?? ahora;
    _tipo = alarma?.tipoProgramacion ?? TipoProgramacionAlarma.unica;
    _diasSemana = {...alarma?.diasSemana ?? const <int>[]};
    _snooze = alarma?.snoozeMinutos ?? 5;
    _volumen = alarma?.volumen ?? 0.85;
    _sonarEnVacaciones = alarma?.sonarEnVacaciones ?? true;
    _sonidoInterno = alarma?.sonidoInterno ?? SonidoInternoAlarma.amanecer;
    _emisora = alarma?.emisora ?? context.read<EstadoRadio>().emisoraPreferida;
  }

  @override
  void dispose() {
    _nombreController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final radio = context.watch<EstadoRadio>();
    final bottom = MediaQuery.of(context).viewInsets.bottom;
    if (!_favoritosSolicitados) {
      _favoritosSolicitados = true;
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) context.read<EstadoRadio>().cargarFavoritos();
      });
    }
    if (_emisora == null && widget.alarma == null && radio.emisoraPreferida != null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted && _emisora == null) {
          setState(() => _emisora = radio.emisoraPreferida);
        }
      });
    }
    final favoritas = _favoritasConSeleccion(radio.listaFavoritos);
    return Padding(
      padding: EdgeInsets.fromLTRB(12, 12, 12, bottom + 12),
      child: PluriGlassSurface(
        borderRadius: BorderRadius.circular(28),
        padding: const EdgeInsets.all(18),
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  const _AssetIcon('assets/icons/alarmas/alarm_music.png', size: 58),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Text(
                      widget.alarma == null ? 'Nueva alarma' : 'Editar alarma',
                      style: Theme.of(context).textTheme.titleLarge?.copyWith(
                        fontWeight: FontWeight.w900,
                      ),
                    ),
                  ),
                  IconButton(
                    icon: const Icon(Icons.close_rounded),
                    onPressed: () => Navigator.pop(context),
                  ),
                ],
              ),
              const SizedBox(height: 14),
              TextField(
                controller: _nombreController,
                decoration: const InputDecoration(labelText: 'Nombre'),
              ),
              const SizedBox(height: 12),
              Row(
                children: [
                  Expanded(
                    child: _PickerButton(
                      icon: Icons.schedule_rounded,
                      label: 'Hora',
                      value: _hora.format(context),
                      onTap: _elegirHora,
                    ),
                  ),
                  const SizedBox(width: 10),
                  Expanded(
                    child: _PickerButton(
                      icon: Icons.event_rounded,
                      label: 'Fecha',
                      value: _fechaCorta(_fecha),
                      onTap: _tipo == TipoProgramacionAlarma.unica ? _elegirFecha : null,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 12),
              SegmentedButton<TipoProgramacionAlarma>(
                segments: const [
                  ButtonSegment(value: TipoProgramacionAlarma.unica, label: Text('Una vez')),
                  ButtonSegment(value: TipoProgramacionAlarma.diaria, label: Text('Diaria')),
                  ButtonSegment(value: TipoProgramacionAlarma.diasSemana, label: Text('Días')),
                ],
                selected: {_tipo},
                onSelectionChanged: (value) => setState(() => _tipo = value.first),
              ),
              if (_tipo == TipoProgramacionAlarma.diasSemana) ...[
                const SizedBox(height: 10),
                Wrap(
                  spacing: 6,
                  children: [
                    for (var i = DateTime.monday; i <= DateTime.sunday; i++)
                      FilterChip(
                        label: Text(_diaCorto(i)),
                        selected: _diasSemana.contains(i),
                        onSelected: (selected) => setState(() {
                          selected ? _diasSemana.add(i) : _diasSemana.remove(i);
                        }),
                      ),
                  ],
                ),
              ],
              const SizedBox(height: 14),
              _SectionLabel(icon: 'assets/icons/alarmas/snooze_wave.png', text: 'Postponer'),
              SegmentedButton<int>(
                segments: const [
                  ButtonSegment(value: 3, label: Text('3 min')),
                  ButtonSegment(value: 5, label: Text('5 min')),
                  ButtonSegment(value: 10, label: Text('10 min')),
                ],
                selected: {_snooze},
                onSelectionChanged: (value) => setState(() => _snooze = value.first),
              ),
              const SizedBox(height: 14),
              _SectionLabel(icon: 'assets/icons/alarmas/fallback_sound.png', text: 'Sonido y volumen'),
              Slider(
                value: _volumen,
                min: 0.25,
                max: 1,
                divisions: 15,
                label: '${(_volumen * 100).round()}%',
                onChanged: (value) => setState(() => _volumen = value),
              ),
              DropdownButtonFormField<SonidoInternoAlarma>(
                initialValue: _sonidoInterno,
                decoration: const InputDecoration(labelText: 'Sonido seguro interno'),
                items: const [
                  DropdownMenuItem(value: SonidoInternoAlarma.amanecer, child: Text('Amanecer cálido')),
                  DropdownMenuItem(value: SonidoInternoAlarma.campanaSuave, child: Text('Campana suave')),
                  DropdownMenuItem(value: SonidoInternoAlarma.pulsoDigital, child: Text('Pulso digital')),
                ],
                onChanged: (value) => setState(() => _sonidoInterno = value ?? _sonidoInterno),
              ),
              const SizedBox(height: 8),
              DropdownButtonFormField<String>(
                key: ValueKey(_emisora?.uuid ?? 'sin-emisora'),
                initialValue: _emisora?.uuid,
                decoration: const InputDecoration(
                  labelText: 'Emisora favorita',
                  prefixIcon: Icon(Icons.radio_rounded),
                ),
                items: [
                  const DropdownMenuItem<String>(
                    value: '',
                    child: Text('Sin emisora: usar sonido interno'),
                  ),
                  for (final emisora in favoritas)
                    DropdownMenuItem<String>(
                      value: emisora.uuid,
                      child: Text(
                        emisora.nombre,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                ],
                onChanged: (uuid) => setState(() {
                  if (uuid == null || uuid.isEmpty) {
                    _emisora = null;
                    return;
                  }
                  _emisora = favoritas.firstWhere((e) => e.uuid == uuid);
                }),
              ),
              if (favoritas.isEmpty) ...[
                const SizedBox(height: 6),
                const Text(
                  'Guardá emisoras en Favoritos para usarlas como alarma musical.',
                ),
              ],
              if (radio.emisoraActual != null) ...[
                const SizedBox(height: 8),
                Align(
                  alignment: Alignment.centerLeft,
                  child: FilledButton.tonalIcon(
                    onPressed: () => setState(() => _emisora = radio.emisoraActual),
                    icon: const Icon(Icons.add_task_rounded),
                    label: const Text('Usar emisora actual'),
                  ),
                ),
              ],
              const SizedBox(height: 8),
              SwitchListTile.adaptive(
                contentPadding: EdgeInsets.zero,
                value: _sonarEnVacaciones,
                onChanged: (value) => setState(() => _sonarEnVacaciones = value),
                secondary: const _AssetIcon('assets/icons/alarmas/vacation_wave.png', size: 42),
                title: const Text('Sonar durante vacaciones'),
                subtitle: const Text('Si lo apagás, la próxima ejecución saltará al primer día válido.'),
              ),
              const SizedBox(height: 16),
              FilledButton.icon(
                onPressed: _guardar,
                icon: const Icon(Icons.check_rounded),
                label: const Text('Guardar alarma'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _elegirHora() async {
    final nueva = await showTimePicker(context: context, initialTime: _hora);
    if (nueva != null) setState(() => _hora = nueva);
  }

  Future<void> _elegirFecha() async {
    final ahora = DateTime.now();
    final nueva = await showDatePicker(
      context: context,
      initialDate: _fecha.isBefore(ahora) ? ahora : _fecha,
      firstDate: DateTime(ahora.year, ahora.month, ahora.day),
      lastDate: ahora.add(const Duration(days: 730)),
    );
    if (nueva != null) setState(() => _fecha = nueva);
  }

  Future<void> _guardar() async {
    if (_tipo == TipoProgramacionAlarma.diasSemana && _diasSemana.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Elegí al menos un día de la semana.')),
      );
      return;
    }

    final estado = context.read<EstadoAlarmas>();
    final existente = widget.alarma;
    final alarma = (existente ??
            estado.servicio.crearAlarma(
              nombre: _nombreController.text.trim(),
              hora: _hora.hour,
              minuto: _hora.minute,
              tipoProgramacion: _tipo,
              diasSemana: _diasSemana.toList()..sort(),
            ))
        .copyWith(
      nombre: _nombreController.text.trim().isEmpty
          ? 'Despertador musical'
          : _nombreController.text.trim(),
      hora: _hora.hour,
      minuto: _hora.minute,
      tipoProgramacion: _tipo,
      diasSemana: _tipo == TipoProgramacionAlarma.diasSemana
          ? (_diasSemana.toList()..sort())
          : const [],
      fechaUnica: _tipo == TipoProgramacionAlarma.unica ? _fecha : null,
      limpiarFechaUnica: _tipo != TipoProgramacionAlarma.unica,
      emisora: _emisora,
      sonarEnVacaciones: _sonarEnVacaciones,
      snoozeMinutos: _snooze,
      volumen: _volumen,
      sonidoInterno: _sonidoInterno,
      activa: true,
    );
    await estado.guardarAlarma(alarma);
    if (mounted) Navigator.pop(context);
  }

  List<Emisora> _favoritasConSeleccion(List<Emisora> favoritas) {
    final mapa = <String, Emisora>{};
    for (final emisora in favoritas) {
      mapa[emisora.uuid] = emisora;
    }
    final seleccionada = _emisora;
    if (seleccionada != null) {
      mapa[seleccionada.uuid] = seleccionada;
    }
    return mapa.values.toList();
  }
}

class _AccesoDiagnostico extends StatelessWidget {
  const _AccesoDiagnostico({required this.estado});

  final EstadoAlarmas estado;

  @override
  Widget build(BuildContext context) {
    final diag = estado.diagnostico;
    return TextButton.icon(
      icon: const _AssetIcon('assets/icons/alarmas/android_reliability.png', size: 28),
      label: Text(
        diag == null
            ? 'Revisar fiabilidad Android'
            : 'Fiabilidad: exactas ${diag.puedeProgramarExactas ? 'OK' : 'pendiente'} · notificaciones ${diag.notificacionesPermitidas ? 'OK' : 'pendiente'}',
      ),
      onPressed: estado.cargarDiagnostico,
    );
  }
}

class _PanelVacaciones extends StatelessWidget {
  const _PanelVacaciones({required this.estado});

  final EstadoAlarmas estado;

  @override
  Widget build(BuildContext context) {
    final vacaciones = [...estado.vacaciones]
      ..sort((a, b) => a.inicioDia.compareTo(b.inicioDia));
    return PluriGlassSurface(
      glowColor: const Color(0xFF60A5FA).withValues(alpha: 0.22),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              const _AssetIcon('assets/icons/alarmas/vacation_wave.png', size: 48),
              const SizedBox(width: 10),
              Expanded(
                child: Text(
                  'Rangos de vacaciones',
                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
                    fontWeight: FontWeight.w900,
                  ),
                ),
              ),
              FilledButton.tonalIcon(
                onPressed: () => _abrirAlta(context),
                icon: const Icon(Icons.add_rounded),
                label: const Text('Agregar'),
              ),
            ],
          ),
          const SizedBox(height: 8),
          Text(
            'Si una alarma tiene "Pausa en vacaciones", se salta automáticamente estos rangos.',
          ),
          const SizedBox(height: 10),
          if (vacaciones.isEmpty)
            const Text('Sin rangos cargados.')
          else
            for (final rango in vacaciones)
              ListTile(
                contentPadding: EdgeInsets.zero,
                leading: const Icon(Icons.event_busy_rounded),
                title: Text(rango.nombre),
                subtitle: Text(
                  '${_fechaCorta(rango.inicioDia)} → ${_fechaCorta(rango.finDia)}',
                ),
                trailing: IconButton(
                  tooltip: 'Eliminar rango',
                  onPressed: () => estado.eliminarRangoVacaciones(rango.id),
                  icon: const Icon(Icons.delete_outline_rounded),
                ),
              ),
        ],
      ),
    );
  }

  Future<void> _abrirAlta(BuildContext context) async {
    await showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      useSafeArea: true,
      backgroundColor: Colors.transparent,
      builder: (_) => const _EditorVacacionesSheet(),
    );
  }
}

class _EditorVacacionesSheet extends StatefulWidget {
  const _EditorVacacionesSheet();

  @override
  State<_EditorVacacionesSheet> createState() => _EditorVacacionesSheetState();
}

class _EditorVacacionesSheetState extends State<_EditorVacacionesSheet> {
  late final TextEditingController _nombreController;
  late DateTime _inicio;
  late DateTime _fin;

  @override
  void initState() {
    super.initState();
    final hoy = DateTime.now();
    _inicio = DateTime(hoy.year, hoy.month, hoy.day);
    _fin = _inicio.add(const Duration(days: 2));
    _nombreController = TextEditingController(text: 'Vacaciones');
  }

  @override
  void dispose() {
    _nombreController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final bottom = MediaQuery.of(context).viewInsets.bottom;
    return Padding(
      padding: EdgeInsets.fromLTRB(12, 12, 12, bottom + 12),
      child: PluriGlassSurface(
        borderRadius: BorderRadius.circular(28),
        padding: const EdgeInsets.all(18),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Nuevo rango de vacaciones',
              style: Theme.of(context).textTheme.titleLarge?.copyWith(
                fontWeight: FontWeight.w900,
              ),
            ),
            const SizedBox(height: 12),
            TextField(
              controller: _nombreController,
              decoration: const InputDecoration(labelText: 'Nombre'),
            ),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: _PickerButton(
                    icon: Icons.play_arrow_rounded,
                    label: 'Inicio',
                    value: _fechaCorta(_inicio),
                    onTap: () => _elegirFecha(esInicio: true),
                  ),
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: _PickerButton(
                    icon: Icons.stop_rounded,
                    label: 'Fin',
                    value: _fechaCorta(_fin),
                    onTap: () => _elegirFecha(esInicio: false),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),
            FilledButton.icon(
              onPressed: _guardar,
              icon: const Icon(Icons.check_rounded),
              label: const Text('Guardar rango'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _elegirFecha({required bool esInicio}) async {
    final actual = esInicio ? _inicio : _fin;
    final hoy = DateTime.now();
    final seleccion = await showDatePicker(
      context: context,
      initialDate: actual,
      firstDate: DateTime(hoy.year, hoy.month, hoy.day),
      lastDate: hoy.add(const Duration(days: 1460)),
    );
    if (seleccion == null) return;
    setState(() {
      if (esInicio) {
        _inicio = seleccion;
        if (_fin.isBefore(_inicio)) _fin = _inicio;
      } else {
        _fin = seleccion;
      }
    });
  }

  Future<void> _guardar() async {
    final estado = context.read<EstadoAlarmas>();
    final rango = estado.servicio.crearRangoVacaciones(
      inicio: _inicio,
      fin: _fin,
      nombre: _nombreController.text.trim(),
    );
    await estado.crearRangoVacaciones(rango);
    if (mounted) Navigator.pop(context);
  }
}

class _AssetIcon extends StatelessWidget {
  const _AssetIcon(this.asset, {this.size = 44});

  final String asset;
  final double size;

  @override
  Widget build(BuildContext context) {
    return Image.asset(
      asset,
      width: size,
      height: size,
      fit: BoxFit.contain,
      errorBuilder: (_, __, ___) => Icon(Icons.music_note_rounded, size: size * 0.65),
    );
  }
}

class _PickerButton extends StatelessWidget {
  const _PickerButton({
    required this.icon,
    required this.label,
    required this.value,
    required this.onTap,
  });

  final IconData icon;
  final String label;
  final String value;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return OutlinedButton.icon(
      onPressed: onTap,
      icon: Icon(icon),
      label: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label, style: Theme.of(context).textTheme.labelSmall),
          Text(value),
        ],
      ),
    );
  }
}

class _SectionLabel extends StatelessWidget {
  const _SectionLabel({required this.icon, required this.text});

  final String icon;
  final String text;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        _AssetIcon(icon, size: 34),
        const SizedBox(width: 8),
        Text(text, style: Theme.of(context).textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w800)),
      ],
    );
  }
}

class _InfoChip extends StatelessWidget {
  const _InfoChip({required this.icon, required this.label});

  final IconData icon;
  final String label;

  @override
  Widget build(BuildContext context) {
    return Chip(avatar: Icon(icon, size: 16), label: Text(label));
  }
}

class _NoticeLine extends StatelessWidget {
  const _NoticeLine({required this.icon, required this.text});

  final IconData icon;
  final String text;

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Icon(icon, size: 18),
        const SizedBox(width: 8),
        Expanded(child: Text(text)),
      ],
    );
  }
}

class _EmptyAlarmas extends StatelessWidget {
  const _EmptyAlarmas();

  @override
  Widget build(BuildContext context) {
    return const PluriGlassSurface(
      child: Column(
        children: [
          _AssetIcon('assets/icons/alarmas/alarm_music.png', size: 92),
          SizedBox(height: 12),
          Text('Todavía no hay alarmas.'),
          SizedBox(height: 4),
          Text('Creá una para diseñar tu despertar musical.'),
        ],
      ),
    );
  }
}

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 · ${_fechaCorta(alarma.fechaUnica ?? DateTime.now())}',
    TipoProgramacionAlarma.diaria => 'Diaria',
    TipoProgramacionAlarma.diasSemana => 'Días: ${alarma.diasSemana.map(_diaCorto).join(', ')}',
  };
}

String _fechaHora(DateTime fecha) {
  final local = fecha.toLocal();
  return '${_diaLargo(local.weekday)} ${local.day} de ${_mes(local.month)} a las '
      '${local.hour.toString().padLeft(2, '0')}:${local.minute.toString().padLeft(2, '0')}';
}

String _fechaCorta(DateTime fecha) =>
    '${fecha.day.toString().padLeft(2, '0')}/${fecha.month.toString().padLeft(2, '0')}/${fecha.year}';

String _diaCorto(int dia) => switch (dia) {
      DateTime.monday => 'Lun',
      DateTime.tuesday => 'Mar',
      DateTime.wednesday => 'Mié',
      DateTime.thursday => 'Jue',
      DateTime.friday => 'Vie',
      DateTime.saturday => 'Sáb',
      DateTime.sunday => 'Dom',
      _ => '?',
    };

String _diaLargo(int dia) => switch (dia) {
      DateTime.monday => 'lunes',
      DateTime.tuesday => 'martes',
      DateTime.wednesday => 'miércoles',
      DateTime.thursday => 'jueves',
      DateTime.friday => 'viernes',
      DateTime.saturday => 'sábado',
      DateTime.sunday => 'domingo',
      _ => 'día',
    };

String _mes(int mes) => switch (mes) {
      1 => 'enero',
      2 => 'febrero',
      3 => 'marzo',
      4 => 'abril',
      5 => 'mayo',
      6 => 'junio',
      7 => 'julio',
      8 => 'agosto',
      9 => 'septiembre',
      10 => 'octubre',
      11 => 'noviembre',
      12 => 'diciembre',
      _ => 'mes',
    };
