import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:nut_player_example/src/features/player_screen/domain/bloc/playerview_bloc.dart';
part 'custom_skin_event.dart';
part 'custom_skin_state.dart';

class CustomSkinBloc extends Bloc<CustomSkinEvent, CustomSkinState> {
  final PlayerViewBloc _bloc;

  CustomSkinBloc(this._bloc):  super(CustomSkin.create()) {
    _onInitialize();
    on<ValueChanged>(_onValueChanged);
    on<SkinVisibilityChanged>(_onSkinVisibilityChanged);
    on<CurrentPositionChanged>(_onCurrentPositionChanged);
    on<PlaybackChanged>(_onPlaybackChanged);
    on<PlayerSeekEvent>(_onPlayerSeekEvent);
    on<PlayerSeekBackEvent>(_onPlayerSeekBackEvent);
    on<PlayerSeekForwardEvent>(_onPlayerSeekForwardEvent);
  }

  _onInitialize() {
      _bloc.controller.addListener(() {
        add(ValueChanged(
            _bloc.controller.value.isPlaying,
            _bloc.controller.value.duration.inSeconds.toDouble(),
            _bloc.controller.value.position.inSeconds.toDouble()
        ));
      });
  }

  _onValueChanged(ValueChanged event, Emitter<CustomSkinState> emit) {
    final skinState = state;
    if (skinState is! CustomSkin) { return; }

    emit(skinState.copy(
      isPlaying: event.isPlaying,
      duration: event.duration,
      currentPosition: event.time
    ));
  }

  _onSkinVisibilityChanged(SkinVisibilityChanged event, Emitter<CustomSkinState> emit) {
    final skinState = state;
    if (skinState is! CustomSkin) { return; }
    
    emit(skinState.copy(isVisible: !skinState.isVisible));
  }

  _onCurrentPositionChanged(CurrentPositionChanged event, Emitter<CustomSkinState> emit) {
    final skinState = state;
    if (skinState is! CustomSkin) { return; }

    emit(skinState.copy(currentPosition: event.time));
  }

  _onPlaybackChanged(PlaybackChanged event, Emitter<CustomSkinState> emit) {
    final skinState = state;
    if (skinState is! CustomSkin) { return; }

    _bloc.add(skinState.isPlaying ? const PauseEvent() : const PlayEvent());
  }

  _onPlayerSeekBackEvent(PlayerSeekBackEvent event, Emitter<CustomSkinState> emit) async {
    final currentTime = await _bloc.controller.position;
    if (currentTime != null) {
      final seekTime = currentTime.inSeconds - 15;
      _bloc.add(SeekEvent(seekTime.toDouble()));
    }
  }

  _onPlayerSeekForwardEvent(PlayerSeekForwardEvent event, Emitter<CustomSkinState> emit) async {
    final currentTime = await _bloc.controller.position;
    if (currentTime != null) {
      final seekTime = currentTime.inSeconds + 15;
      _bloc.add(SeekEvent(seekTime.toDouble()));
    }
  }

  _onPlayerSeekEvent(PlayerSeekEvent event, Emitter<CustomSkinState> emit) {
    _bloc.add(SeekEvent(event.time));
  }

}
