import 'package:flutter/material.dart';

import '../../../extensions/date_time.dart';
import '../../../state/app/infrastructure/loadable_state/loadable_state.dart';
import '../../../state/app/infrastructure/loadable_state/view/loadable_state_consumer.dart';
import '../../../state/app/infrastructure/utility_widgets/bloc_module.dart';
import '../../../state/app/modules/marianum_dates/bloc/marianum_dates_bloc.dart';
import '../../../state/app/modules/marianum_dates/bloc/marianum_dates_event.dart';
import '../../../state/app/modules/marianum_dates/bloc/marianum_dates_state.dart';
import '../../../widget/placeholder_view.dart';
import 'search_marianum_dates.dart';
import 'widgets/event_list_tile.dart';
import 'widgets/month_section_header.dart';

class MarianumDatesView extends StatelessWidget {
  const MarianumDatesView({super.key});

  /// Groups events by `yyyy-MM` (chronological). Uses the event's start date.
  static List<_MonthGroup> _groupByMonth(List<MarianumDate> events) {
    final byMonth = <String, List<MarianumDate>>{};
    for (final e in events) {
      final key =
          '${e.start.year.toString().padLeft(4, '0')}-${e.start.month.toString().padLeft(2, '0')}';
      byMonth.putIfAbsent(key, () => []).add(e);
    }
    final keys = byMonth.keys.toList()..sort();
    return keys.map((key) {
      final first = byMonth[key]!.first.start;
      final label = first.formatMonthYear().toUpperCase();
      return _MonthGroup(label: label, events: byMonth[key]!);
    }).toList();
  }

  @override
  Widget build(
    BuildContext context,
  ) => BlocModule<MarianumDatesBloc, LoadableState<MarianumDatesState>>(
    create: (context) => MarianumDatesBloc(),
    autoRebuild: true,
    child: (context, bloc, state) => Scaffold(
      appBar: AppBar(
        title: const Text('Marianum Termine'),
        actions: [
          PopupMenuButton<bool>(
            tooltip:
                'Vergangene Termine ${bloc.showPastEvents() ? 'ausblenden' : 'anzeigen'}',
            initialValue: bloc.showPastEvents(),
            icon: const Icon(Icons.history),
            itemBuilder: (context) => [true, false]
                .map(
                  (e) => PopupMenuItem<bool>(
                    value: e,
                    enabled: e != bloc.showPastEvents(),
                    child: Row(
                      children: [
                        Icon(
                          e
                              ? Icons.history_outlined
                              : Icons.history_toggle_off_outlined,
                          color: Theme.of(context).colorScheme.onSurface,
                        ),
                        const SizedBox(width: 15),
                        Text(e ? 'Alle anzeigen' : 'Nur zukünftige anzeigen'),
                      ],
                    ),
                  ),
                )
                .toList(),
            onSelected: (e) => bloc.add(SetPastEventsVisible(e)),
          ),
          IconButton(
            tooltip: 'Suchen',
            icon: const Icon(Icons.search),
            onPressed: () {
              final events = bloc.getEvents() ?? const <MarianumDate>[];
              showSearch(
                context: context,
                delegate: SearchMarianumDates(events),
              );
            },
          ),
        ],
      ),
      body: LoadableStateConsumer<MarianumDatesBloc, MarianumDatesState>(
        child: (state, loading) {
          final events = bloc.getEvents() ?? const <MarianumDate>[];
          final groups = _groupByMonth(events);

          if (groups.isEmpty) {
            return const PlaceholderView(
              icon: Icons.event_busy_outlined,
              text: 'Keine Termine',
            );
          }

          return CustomScrollView(
            slivers: [
              for (final group in groups)
                SliverMainAxisGroup(
                  slivers: [
                    SliverPersistentHeader(
                      pinned: true,
                      delegate: MonthHeaderDelegate(label: group.label),
                    ),
                    SliverList.builder(
                      itemCount: group.events.length,
                      itemBuilder: (_, i) =>
                          MarianumDateRow(event: group.events[i]),
                    ),
                  ],
                ),
              const SliverToBoxAdapter(child: SizedBox(height: 24)),
            ],
          );
        },
      ),
    ),
  );
}

class _MonthGroup {
  final String label;
  final List<MarianumDate> events;
  _MonthGroup({required this.label, required this.events});
}
