content: import 'dart:async';
  
  import 'package:flutter/material.dart';
  
  import 'package:go_router/go_router.dart';
  import 'package:matrix/matrix.dart';
  
  import 'package:fluffychat/l10n/l10n.dart';
  import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
  import 'package:fluffychat/widgets/future_loading_dialog.dart';
  import 'matrix.dart';
  
  enum ChatPopupMenuActions { details, mute, unmute, emote, leave, search }
  
  class ChatSettingsPopupMenu extends StatefulWidget {
    final Room room;
    final bool displayChatDetails;
  
    const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {super.key});
  
    @override
    ChatSettingsPopupMenuState createState() => ChatSettingsPopupMenuState();
  }
  
  class ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
    StreamSubscription? notificationChangeSub;
  
    @override
    void dispose() {
      notificationChangeSub?.cancel();
      super.dispose();
    }
  
    void goToEmoteSettings() async {
      final room = widget.room;
      // okay, we need to test if there are any emote state events other than the default one
      // if so, we need to be directed to a selection screen for which pack we want to look at
      // otherwise, we just open the normal one.
      if ((room.states['im.ponies.room_emotes'] ?? <String, Event>{})
          .keys
          .any((String s) => s.isNotEmpty)) {
        context.push('/rooms/${room.id}/details/multiple_emotes');
      } else {
        context.push('/rooms/${room.id}/details/emotes');
      }
    }
  
    @override
    Widget build(BuildContext context) {
      notificationChangeSub ??= Matrix.of(context)
          .client
          .onSync
          .stream
          .where(
            (syncUpdate) =>
                syncUpdate.accountData?.any(
                  (accountData) => accountData.type == 'm.push_rules',
                ) ??
                false,
          )
          .listen(
            (u) => setState(() {}),
          );
      return Stack(
        alignment: Alignment.center,
        children: [
          const SizedBox.shrink(),
          PopupMenuButton<ChatPopupMenuActions>(
            useRootNavigator: true,
            onSelected: (choice) async {
              switch (choice) {
                case ChatPopupMenuActions.leave:
                  final router = GoRouter.of(context);
                  final confirmed = await showOkCancelAlertDialog(
                    context: context,
                    title: L10n.of(context).areYouSure,
                    message: L10n.of(context).archiveRoomDescription,
                    okLabel: L10n.of(context).leave,
                    cancelLabel: L10n.of(context).cancel,
                    isDestructive: true,
                  );
                  if (confirmed != OkCancelResult.ok) return;
                  final result = await showFutureLoadingDialog(
                    context: context,
                    future: () => widget.room.leave(),
                  );
                  if (result.error == null) {
                    router.go('/rooms');
                  }
  
                  break;
                case ChatPopupMenuActions.mute:
                  await showFutureLoadingDialog(
                    context: context,
                    future: () =>
                        widget.room.setPushRuleState(PushRuleState.mentionsOnly),
                  );
                  break;
                case ChatPopupMenuActions.unmute:
                  await showFutureLoadingDialog(
                    context: context,
                    future: () =>
                        widget.room.setPushRuleState(PushRuleState.notify),
                  );
                  break;
                case ChatPopupMenuActions.details:
                  _showChatDetails();
                  break;
                case ChatPopupMenuActions.search:
                  context.go('/rooms/${widget.room.id}/search');
                  break;
                case ChatPopupMenuActions.emote:
                  goToEmoteSettings();
              }
            },
            itemBuilder: (BuildContext context) => [
              if (widget.displayChatDetails)
                PopupMenuItem<ChatPopupMenuActions>(
                  value: ChatPopupMenuActions.details,
                  child: Row(
                    children: [
                      const Icon(Icons.info_outline_rounded),
                      const SizedBox(width: 12),
                      Text(L10n.of(context).chatDetails),
                    ],
                  ),
                ),
              if (widget.room.pushRuleState == PushRuleState.notify)
                PopupMenuItem<ChatPopupMenuActions>(
                  value: ChatPopupMenuActions.mute,
                  child: Row(
                    children: [
                      const Icon(Icons.notifications_off_outlined),
                      const SizedBox(width: 12),
                      Text(L10n.of(context).muteChat),
                    ],
                  ),
                )
              else
                PopupMenuItem<ChatPopupMenuActions>(
                  value: ChatPopupMenuActions.unmute,
                  child: Row(
                    children: [
                      const Icon(Icons.notifications_on_outlined),
                      const SizedBox(width: 12),
                      Text(L10n.of(context).unmuteChat),
                    ],
                  ),
                ),
              PopupMenuItem<ChatPopupMenuActions>(
                value: ChatPopupMenuActions.search,
                child: Row(
                  children: [
                    const Icon(Icons.search_outlined),
                    const SizedBox(width: 12),
                    Text(L10n.of(context).search),
                  ],
                ),
              ),
              PopupMenuItem<ChatPopupMenuActions>(
                value: ChatPopupMenuActions.emote,
                child: Row(
                  children: [
                    const Icon(Icons.emoji_emotions_outlined),
                    const SizedBox(width: 12),
                    Text(L10n.of(context).emoteSettings),
                  ],
                ),
              ),
              PopupMenuItem<ChatPopupMenuActions>(
                value: ChatPopupMenuActions.leave,
                child: Row(
                  children: [
                    const Icon(Icons.delete_outlined),
                    const SizedBox(width: 12),
                    Text(L10n.of(context).leave),
                  ],
                ),
              ),
            ],
          ),
        ],
      );
    }
  
    void _showChatDetails() {
      if (GoRouterState.of(context).uri.path.endsWith('/details')) {
        context.go('/rooms/${widget.room.id}');
      } else {
        context.go('/rooms/${widget.room.id}/details');
      }
    }
  }
  