import 'package:comunic/helpers/events_helper.dart';
import 'package:comunic/helpers/notifications_helper.dart';
import 'package:comunic/helpers/preferences_helper.dart';
import 'package:comunic/models/count_unread_notifications.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/screens/notifications_screen.dart';
import 'package:comunic/ui/screens/unread_conversations_screen.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/ui/widgets/tablet_mode/appbar_custom_dropdown_widget.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';

/// Comunic tablet AppBar widget
///
/// @author Pierre Hubert

class ComunicTabletAppBarWidget extends StatefulWidget
    implements PreferredSizeWidget {
  @override
  _ComunicTabletAppBarWidgetState createState() =>
      _ComunicTabletAppBarWidgetState();

  @override
  Size get preferredSize => Size.fromHeight(kToolbarHeight);
}

class _ComunicTabletAppBarWidgetState
    extends SafeState<ComunicTabletAppBarWidget> {
  final notificationsDropdownKey = GlobalKey<AppBarCustomDropDownWidgetState>();
  final conversationsDropdownKey = GlobalKey<AppBarCustomDropDownWidgetState>();

  var _unreadNotifications =
      CountUnreadNotifications(notifications: 0, conversations: 0);

  void _refreshCountUnread() async {
    try {
      final count = await NotificationsHelper().countUnread();

      setState(() {
        _unreadNotifications = count;
      });
    } catch (e, s) {
      print("Could not refresh the number of unread notifications: $e\n$s");
    }
  }

  @override
  void initState() {
    super.initState();

    _refreshCountUnread();

    // Listen to notifications number update
    this.listenChangeState<NewNumberNotifsEvent>(
        (d) => _unreadNotifications.notifications = d.newNum);
    this.listenChangeState<NewNumberUnreadConversations>(
        (d) => _unreadNotifications.conversations = d.newNum);
  }

  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: GestureDetector(
          child: Text("Comunic"),
          onTap: () => MainController.of(context).openLatestPostsPage()),
      actions: <Widget>[
        AppBarCustomDropDownWidget(
          key: notificationsDropdownKey,
          icon: Icon(Icons.notifications),
          notificationsBadge: _unreadNotifications.notifications,
          onBuildOverlay: (c) => Padding(
            padding: const EdgeInsets.all(8.0),
            child: NotificationsScreen(useSmallDeleteButton: true),
          ),
        ),
        AppBarCustomDropDownWidget(
          key: conversationsDropdownKey,
          icon: Icon(Icons.message),
          notificationsBadge: _unreadNotifications.conversations,
          onBuildOverlay: (c) => Padding(
            padding: const EdgeInsets.all(8.0),
            child: UnreadConversationsScreen(),
          ),
        ),
        PopupMenuButton<_MenuItemCallback>(
          offset: Offset(0, 50),
          itemBuilder: (c) => [
            // Get groups
            _MainMenuItem(
                label: tr("Groups"),
                icon: Icons.group,
                onTap: () => MainController.of(context).openGroupsListPage()),

            // Toggle dark theme
            _MainMenuItem(
                label: tr("Night mode"),
                icon: preferences().preferences.enableDarkMode
                    ? Icons.brightness_2
                    : Icons.wb_sunny,
                onTap: _toggleDarkMode),

            // Open settings
            _MainMenuItem(
                label: tr("Settings"),
                icon: Icons.settings,
                onTap: () => MainController.of(context).openSettings()),

            // Sign out
            _MainMenuItem(
                label: tr("Sign out"),
                icon: Icons.power_settings_new,
                onTap: () => MainController.of(context).requestLogout()),
          ],
          onSelected: (v) => v(),
        ),
      ],
    );
  }

  /// Toggle dark mode
  void _toggleDarkMode() async {
    final prefs = preferences().preferences;
    prefs.enableDarkMode = !prefs.enableDarkMode;
    await preferences().setPreferences(prefs);

    applyNewThemeSettings(context);
  }
}

typedef _MenuItemCallback = void Function();

class _MainMenuItem extends PopupMenuEntry<_MenuItemCallback> {
  final String label;
  final IconData icon;
  final _MenuItemCallback onTap;

  const _MainMenuItem({
    @required this.label,
    @required this.icon,
    @required this.onTap,
  })  : assert(label != null),
        assert(icon != null),
        assert(onTap != null);

  @override
  __MainMenuItemState createState() => __MainMenuItemState();

  @override
  double get height => kMinInteractiveDimension;

  @override
  bool represents(_MenuItemCallback value) => onTap == value;
}

class __MainMenuItemState extends State<_MainMenuItem> {
  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: Icon(widget.icon),
      title: Text(widget.label),
      onTap: () => Navigator.of(context).pop(widget.onTap),
    );
  }
}