import 'dart:async';
import 'servicio_audio.dart';

/// Opciones predefinidas de timer en minutos.
const opcionesTimer = [3, 5, 10, 15, 30, 60, 90, 120, 180];

/// Servicio de auto-apagado de la radio.
///
/// Cuenta atrás desde la duración elegida. Cuando llega a 0:
/// 1. Hace un fade out de [_fadeDuracion] segundos.
/// 2. Llama a [ServicioAudio.detener].
///
/// El UI puede escuchar [tiempoRestanteStream] para mostrar el contador.
class ServicioTimer {
  final ServicioAudio _audio;

  Timer? _timer;
  Timer? _fadeTicker;
  DateTime? _finAt;
  Duration _tiempoRestante = Duration.zero;
  bool _activo = false;

  static const _fadeDuracion = Duration(seconds: 30);
  static const _fadeStep = Duration(seconds: 1);

  final _controller = StreamController<Duration>.broadcast();

  ServicioTimer(this._audio);

  /// Stream que emite el tiempo restante cada segundo.
  Stream<Duration> get tiempoRestanteStream => _controller.stream;
  Duration get tiempoRestante => _tiempoRestante;
  bool get activo => _activo;

  /// Inicia el timer para [minutos] minutos.
  void iniciar(int minutos) {
    unawaited(cancelar());
    final duracion = Duration(minutes: minutos);
    _finAt = DateTime.now().add(duracion);
    _tiempoRestante = duracion;
    _activo = true;
    _controller.add(_tiempoRestante);

    _timer = Timer.periodic(const Duration(seconds: 1), (_) {
      final ahora = DateTime.now();
      final restante = _finAt!.difference(ahora);

      if (restante <= Duration.zero) {
        _tiempoRestante = Duration.zero;
        _controller.add(_tiempoRestante);

        _timer?.cancel();
        _timer = null;

        _activo = false;

        _iniciarFadeOut();
      } else {
        _tiempoRestante = restante;
        _controller.add(_tiempoRestante);
      }


      // if (restante <= Duration.zero) {
      //   _tiempoRestante = Duration.zero;
      //   _controller.add(_tiempoRestante);
      //   _iniciarFadeOut();
      //   cancelar(detenerAudio: false);
      // } else {
      //   _tiempoRestante = restante;
      //   _controller.add(_tiempoRestante);
      // }
    });
  }

  void _iniciarFadeOut() {
    final pasos = _fadeDuracion.inSeconds;
    final volumenInicial = _audio.volumen;
    int paso = 0;

    _fadeTicker = Timer.periodic(_fadeStep, (_) async {
      paso++;
      final nuevoVolumen = volumenInicial * (1 - paso / pasos);
      await _audio.setVolumen(nuevoVolumen.clamp(0.0, 1.0));

      if (paso >= pasos) {
        _fadeTicker?.cancel();
        await _audio.detener();
        await _audio.setVolumen(volumenInicial); // restaurar volumen para próxima vez
      }
    });
  }

  /// Cancela el timer activo sin detener el audio.
  Future<void> cancelar({bool detenerAudio = false}) async {
    _timer?.cancel();
    _timer = null;
    _fadeTicker?.cancel();
    _fadeTicker = null;
    _activo = false;
    _tiempoRestante = Duration.zero;
    _controller.add(_tiempoRestante);

    if (detenerAudio) {
      await _audio.detener();
    }
  }

  void dispose() {
    unawaited(cancelar());
    _controller.close();
  }
}
