import '../../../../../api/errors/ticker_content_unavailable_exception.dart';
import '../../../../../api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.dart';
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc.dart';
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc_event.dart';
import '../repository/ticker_page_repository.dart';
import 'ticker_page_event.dart';
import 'ticker_page_state.dart';

/// Per-slug loadable bloc for a single ticker page; [id] is the slug so each
/// page keeps its own hydrated cache entry.
class TickerPageBloc
    extends
        LoadableHydratedBloc<
          TickerPageEvent,
          TickerPageState,
          TickerPageRepository
        > {
  final String slug;

  TickerPageBloc(this.slug);

  @override
  String get id => slug;

  @override
  Future<void> gatherData() async {
    try {
      final page = await repo.getPage(slug);
      add(DataGathered((state) => state.copyWith(page: page)));
    } on TickerContentUnavailableException catch (e) {
      // Content, not error: a content-less page keeps the "open in browser"
      // branch and stays cached offline.
      add(
        DataGathered(
          (state) => state.copyWith(
            page: TickerPageResponse(
              schemaVersion: 1,
              slug: slug,
              kind: TickerPageKind.content,
              webUrl: e.webUrl,
            ),
          ),
        ),
      );
    }
  }

  @override
  TickerPageRepository repository() => TickerPageRepository();

  @override
  TickerPageState fromNothing() => const TickerPageState();

  @override
  TickerPageState fromStorage(Map<String, dynamic> json) =>
      TickerPageState.fromJson(json);

  @override
  Map<String, dynamic>? toStorage(TickerPageState state) => state.toJson();
}
