import 'package:comunic/forez/helpers/forez_group_helper.dart';
import 'package:comunic/forez/ui/routes/forez_member_profile_route.dart';
import 'package:comunic/forez/ui/screens/forez_directory_screen.dart';
import 'package:comunic/helpers/events_helper.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/ui/dialogs/alert_dialog.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/routes/main_route/page_info.dart';
import 'package:comunic/ui/screens/conversations_list_screen.dart';
import 'package:comunic/ui/screens/group_sections/forez_presence_section.dart';
import 'package:comunic/ui/screens/group_sections/group_posts_section.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/ui/widgets/status_widget.dart';
import 'package:comunic/ui/widgets/tab_transition_widget.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart';

/// Forez route
///
/// @author Pierre Hubert

class ForezRoute extends StatefulWidget implements MainRoute {
  const ForezRoute({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _MainRouteState();
}

/// Private implementation of HomeController
class _MainRouteState extends MainController {
  final GlobalKey<_ForezRouteBodyState> _mainKey = GlobalKey();

  @override
  PageInfo get defaultPage => PageInfo(
        type: PageType.OTHER_PAGE,
        child: ForezRouteBody(key: _mainKey),
        hideNavBar: true,
      );

  @override
  Widget build(BuildContext context) {
    if (forezGroup == null) return Text(tr("Missing Forez group!"));

    return StatusWidget(
      child: (c) => SafeArea(
        // Avoid OS areas
        child: WillPopScope(
          onWillPop: willPop,
          child: Scaffold(
            appBar: currentPage.hideNavBar ? null : AppBar(),
            body: SafeArea(key: currentPage.key, child: currentPage.child),
          ),
        ),
      ),
    );
  }

  @override
  void pushPage(PageInfo page) {
    if (page.hideNavBar)
      Navigator.of(context).push(MaterialPageRoute(builder: (c) => page.child));
    else
      super.pushPage(page);
  }

  @override
  void openConversation(Conversation conv, {fullScreen: false}) {
    // Forcefully open conversations in a "normal" way (do not display groups)
    openConversationById(conv.id, fullScreen: fullScreen);
  }

  @override
  void openGroup(int groupID, {int conversationID}) => _unsupportedFeature();

  @override
  void openUserPage(int userID) => pushPage(PageInfo(
        child: ForezMemberProfileRoute(userID: userID),
        hideNavBar: true,
        canShowAsDialog: true,
        type: PageType.USER_PAGE,
        id: userID,
      ));

  @override
  void openFriendsList() => _unsupportedFeature();

  void _unsupportedFeature() => alert(context,
      tr("This feature is available only in the Comunic application!"));
}

enum _PopupMenuItems { ACTION_SETTINGS, ACTION_SIGN_OUT }

class ForezRouteBody extends StatefulWidget {
  ForezRouteBody({Key key}) : super(key: key);

  @override
  _ForezRouteBodyState createState() => _ForezRouteBodyState();
}

class _ForezRouteBodyState extends SafeState<ForezRouteBody> {
  @override
  void initState() {
    super.initState();

    listenChangeState<NewNumberUnreadConversations>((event) {});
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tabs.length,
      child: Scaffold(
        appBar: AppBar(
          title: Text(forezGroup.name),
          actions: <Widget>[_buildPopupMenuButton()],
          bottom: TabBar(tabs: _tabs),
        ),
        body: TabBarView(children: _tabsPages),
      ),
    );
  }

  Widget _buildPopupMenuButton() => PopupMenuButton<_PopupMenuItems>(
        itemBuilder: (c) => [
          PopupMenuItem(
            child: Text(tr("Settings")),
            value: _PopupMenuItems.ACTION_SETTINGS,
          ),
          PopupMenuItem(
            child: Text(tr("Sign out")),
            value: _PopupMenuItems.ACTION_SIGN_OUT,
          ),
        ],
        onSelected: _onMenuSelection,
      );

  void _onMenuSelection(_PopupMenuItems value) {
    switch (value) {
      case _PopupMenuItems.ACTION_SETTINGS:
        MainController.of(context).openSettings();
        break;
      case _PopupMenuItems.ACTION_SIGN_OUT:
        MainController.of(context).requestLogout();
        break;
    }
  }

  final _list = <_Tab>[
    // Posts tab
    _Tab(
      icon: Icons.auto_stories,
      title: tr("Posts"),
      widget: () => GroupPostsSection(group: forezGroup),
    ),

    // Presence tab
    _Tab(
      icon: Icons.calendar_today,
      title: tr("Presence"),
      widget: () => ForezPresenceSection(groupID: forezGroup.id),
    ),

    // Conversations tab
    _Tab(
      icon: Icons.question_answer,
      title: tr("Conversations"),
      widget: () => ConversationsListScreen(),
      isUnread: (c) => StatusWidgetState.of(c).unreadConversations > 0,
    ),

    // Directory tab
    _Tab(
      icon: Icons.import_contacts,
      title: tr("Directory"),
      widget: () => ForezDirectoryScreen(),
    ),
  ];

  List<Tab> get _tabs => _list
      .map((e) => Tab(
          icon: Stack(
            children: <Widget>[
              Icon(e.icon),
              e.isUnread?.call(context) ?? false
                  ? Container(color: Colors.red, width: 10, height: 10)
                  : Container(width: 0)
            ],
          ),
          text: e.title))
      .toList();

  List<Widget> get _tabsPages =>
      _list.map((e) => TabTransitionWidget(e.widget())).toList();
}

class _Tab {
  final IconData icon;
  final String title;
  final Widget Function() widget;
  final bool Function(BuildContext) isUnread;

  const _Tab({
    @required this.icon,
    @required this.title,
    @required this.widget,
    this.isUnread,
  })  : assert(icon != null),
        assert(title != null),
        assert(widget != null);
}