import 'dart:async';

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

import 'bloc_module.dart';

class SwappingBloc<TBloc> {
  final TBloc initialBloc;
  final StreamController<TBloc> updater = StreamController<TBloc>();

  SwappingBloc(this.initialBloc);

  void swap(TBloc bloc) {
    updater.add(bloc);
  }
}

class SwappingBlocModule<TBloc extends StateStreamableSource<TState>, TState> extends StatefulWidget {
  final SwappingBloc<TBloc> bloc;
  final Widget Function(BuildContext context, TBloc bloc, TState state) child;
  const SwappingBlocModule({super.key, required this.bloc, required this.child});

  @override
  State<SwappingBlocModule<TBloc, TState>> createState() => _SwappingBlocModuleState<TBloc, TState>();
}

class _SwappingBlocModuleState<TBloc extends StateStreamableSource<TState>, TState> extends State<SwappingBlocModule<TBloc, TState>> {
  late TBloc bloc;

  @override
  void initState() {
    super.initState();
    bloc = widget.bloc.initialBloc;
    widget.bloc.updater.stream.listen((event) {
      setState(() {
        bloc = event;
      });
    });
  }

  @override
  Widget build(BuildContext context) => BlocModule<TBloc, TState>(
    autoRebuild: true,
    create: (context) => bloc,
    child: (context, bloc, state) => widget.child(context, bloc, state),
  );
}