import 'package:flutter/material.dart';

import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:intl/intl.dart';
import 'package:matrix/matrix.dart';

import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/chat/events/video_player.dart';
import 'package:fluffychat/pages/image_viewer/image_viewer.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/mxc_image.dart';

class ChatSearchImagesTab extends StatelessWidget {
  final Room room;
  final Stream<(List<Event>, String?)>? searchStream;
  final void Function({
    String? prevBatch,
    List<Event>? previousSearchResult,
  }) startSearch;

  const ChatSearchImagesTab({
    required this.room,
    required this.startSearch,
    required this.searchStream,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    final borderRadius = BorderRadius.circular(AppConfig.borderRadius / 2);
    return StreamBuilder(
      stream: searchStream,
      builder: (context, snapshot) {
        final theme = Theme.of(context);
        final events = snapshot.data?.$1;
        if (searchStream == null || events == null) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const CircularProgressIndicator.adaptive(strokeWidth: 2),
              const SizedBox(height: 8),
              Text(
                L10n.of(context).searchIn(
                  room.getLocalizedDisplayname(
                    MatrixLocals(L10n.of(context)),
                  ),
                ),
              ),
            ],
          );
        }
        if (events.isEmpty) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.photo_outlined, size: 64),
              const SizedBox(height: 8),
              Text(L10n.of(context).nothingFound),
            ],
          );
        }
        final eventsByMonth = <DateTime, List<Event>>{};
        for (final event in events) {
          final month = DateTime(
            event.originServerTs.year,
            event.originServerTs.month,
          );
          eventsByMonth[month] ??= [];
          eventsByMonth[month]!.add(event);
        }
        final eventsByMonthList = eventsByMonth.entries.toList();

        const padding = 8.0;

        return ListView.builder(
          itemCount: eventsByMonth.length + 1,
          itemBuilder: (context, i) {
            if (i == eventsByMonth.length) {
              if (snapshot.connectionState != ConnectionState.done) {
                return const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: Center(
                    child: CircularProgressIndicator.adaptive(
                      strokeWidth: 2,
                    ),
                  ),
                );
              }
              final nextBatch = snapshot.data?.$2;
              if (nextBatch == null) {
                return const SizedBox.shrink();
              }
              return Center(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: TextButton.icon(
                    style: TextButton.styleFrom(
                      backgroundColor: theme.colorScheme.secondaryContainer,
                      foregroundColor: theme.colorScheme.onSecondaryContainer,
                    ),
                    onPressed: () => startSearch(
                      prevBatch: nextBatch,
                      previousSearchResult: events,
                    ),
                    icon: const Icon(
                      Icons.arrow_downward_outlined,
                    ),
                    label: Text(L10n.of(context).searchMore),
                  ),
                ),
              );
            }

            final monthEvents = eventsByMonthList[i].value;
            return Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const SizedBox(height: 4),
                Row(
                  children: [
                    Expanded(
                      child: Container(
                        height: 1,
                        color: theme.dividerColor,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        DateFormat.yMMMM(
                          Localizations.localeOf(context).languageCode,
                        ).format(eventsByMonthList[i].key),
                        style: theme.textTheme.labelSmall,
                        textAlign: TextAlign.center,
                      ),
                    ),
                    Expanded(
                      child: Container(
                        height: 1,
                        color: theme.dividerColor,
                      ),
                    ),
                  ],
                ),
                GridView.count(
                  physics: const NeverScrollableScrollPhysics(),
                  shrinkWrap: true,
                  mainAxisSpacing: padding,
                  crossAxisSpacing: padding,
                  clipBehavior: Clip.hardEdge,
                  padding: const EdgeInsets.all(padding),
                  crossAxisCount: 3,
                  children: monthEvents.map(
                    (event) {
                      if (event.messageType == MessageTypes.Video) {
                        return Material(
                          clipBehavior: Clip.hardEdge,
                          borderRadius: borderRadius,
                          child: EventVideoPlayer(event),
                        );
                      }
                      return InkWell(
                        onTap: () => showDialog(
                          context: context,
                          builder: (_) => ImageViewer(
                            event,
                            outerContext: context,
                          ),
                        ),
                        borderRadius: borderRadius,
                        child: Material(
                          clipBehavior: Clip.hardEdge,
                          borderRadius: borderRadius,
                          child: MxcImage(
                            event: event,
                            width: 128,
                            height: 128,
                            fit: BoxFit.cover,
                            animated: true,
                            isThumbnail: true,
                          ),
                        ),
                      );
                    },
                  ).toList(),
                ),
              ],
            );
          },
        );
      },
    );
  }
}
