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));

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

  @override
  Stream<TimerState> mapEventToState(
    TimerEvent event,
  ) async* {
    if (event is TimerStart) {
      yield* _mapStartToState(event);
    } else if (event is TimerPause) {
      yield* _mapPauseToState(event);
    } else if (event is TimerResume) {
      yield* _mapResumeToState(event);
    } else if (event is TimerReset) {
      yield* _mapResetToState(event);
    } else if (event is TimerTick) {
      yield* _mapTickToState(event);
    } else if (event is TimerEnd) {
      print("$event");
      if (_tickerSubscription != null) {
        _tickerSubscription!.cancel();
      }
      yield TimerFinished(state.duration);
    }
  }

  @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);
  } */
}