import 'dart:async';

//import 'package:audioplayer/audioplayer.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';

part 'timer_event.dart';
part 'timer_state.dart';

class Ticker {
  Stream<int> tick({required int ticks}) {
    return Stream.periodic(Duration(seconds: 1), (x) => compute(ticks, x)).take(ticks);
  }

  int compute(int ticks, int x) {
    //print("tcik: " + (ticks - x - 1).toString());
    return ticks - x - 1;
  }
}

class TimerBloc extends Bloc<TimerEvent, TimerState> {
  final Ticker _ticker = Ticker();
  int _duration = 0;

  //final AudioPlayer audioPlayer = AudioPlayer();
  int minutes = 0;
  int seconds = 0;

  // ignore: cancel_subscriptions
  StreamSubscription<int>? _tickerSubscription;

  TimerBloc() : super(TimerReady(300)) {
    on<TimerStart>(_onStart);
    on<TimerPause>(_onPause);
    on<TimerResume>(_onResume);
    on<TimerReset>(_onReset);
    on<TimerTick>(_onTick);
    on<TimerEnd>(_onEnd);
  }

  Stream<TimerState> _onStart(TimerStart event, Emitter<TimerState> emit) async* {
    yield* _mapStartToState(event);
  }

  Stream<TimerState> _onPause(TimerPause event, Emitter<TimerState> emit) async* {
    yield* _mapPauseToState(event);
  }

  Stream<TimerState> _onResume(TimerResume event, Emitter<TimerState> emit) async* {
    yield* _mapResumeToState(event);
  }

  Stream<TimerState> _onReset(TimerReset event, Emitter<TimerState> emit) async* {
    yield* _mapResetToState(event);
  }

  Stream<TimerState> _onTick(TimerTick event, Emitter<TimerState> emit) async* {
    yield* _mapTickToState(event);
  }

  void _onEnd(TimerEnd event, Emitter<TimerState> emit) {
    print("$event");
    if (_tickerSubscription != null) {
      _tickerSubscription!.cancel();
    }
    emit(TimerFinished(state.duration));
  }

  @override
  void onTransition(Transition<TimerEvent, TimerState> transition) {
    super.onTransition(transition);
    //print(transition);
  }

  @override
  Future<void> close() {
    if (_tickerSubscription != null) {
      _tickerSubscription!.cancel();
    }
    return super.close();
  }

  Stream<TimerState> _mapStartToState(TimerStart start) async* {
    //print("$start");
    yield TimerRunning(start.duration);
    if (_tickerSubscription != null) {
      _tickerSubscription!.cancel();
    }
    _tickerSubscription = _ticker.tick(ticks: start.duration).listen(
      (localDuration) {
        //print("local: $localDuration");
        add(TimerTick(duration: localDuration));
      },
    );
  }

  Stream<TimerState> _mapPauseToState(TimerPause pause) async* {
    if (state is TimerRunning) {
      if (_tickerSubscription != null) {
        _tickerSubscription!.pause();
      }
      yield TimerPaused(state.duration);
    }
  }

  Stream<TimerState> _mapResumeToState(TimerResume pause) async* {
    if (state is TimerPaused) {
      if (_tickerSubscription != null) {
        _tickerSubscription!.resume();
      }

      yield TimerRunning(state.duration);
    }
  }

  Stream<TimerState> _mapResetToState(TimerReset reset) async* {
    this._duration = 0;
    yield TimerReady(_duration);
  }

  Stream<TimerState> _mapTickToState(TimerTick tick) async* {
    //print("tick $tick");
    yield TickStart(tick.duration);
    yield tick.duration >= 0 ? TimerRunning(tick.duration) : TimerFinished(tick.duration);
  }

  /* Future _play() async {
    await audioPlayer.play('asset/wine-glass.mp3', isLocal: true);
  } */
}