import 'package:comunic/models/advanced_group_info.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/screens/group_sections/about_group_section.dart';
import 'package:comunic/ui/screens/group_sections/group_conversation_section.dart';
import 'package:comunic/ui/screens/group_sections/group_members_screen.dart';
import 'package:comunic/ui/screens/group_sections/group_posts_section.dart';
import 'package:comunic/ui/screens/group_settings_screen.dart';
import 'package:comunic/ui/widgets/group_following_widget.dart';
import 'package:comunic/ui/widgets/group_icon_widget.dart';
import 'package:comunic/ui/widgets/group_membership_widget.dart';
import 'package:comunic/ui/widgets/like_widget.dart';
import 'package:comunic/ui/widgets/post_container_widget.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart';

/// Authorized group page screen
///
/// This screen is shown when the user is allowed to access to a group's page
///
/// @author Pierre Hubert

Color get _headerTextColor => Colors.white;

Color get _headerColor => Colors.blueAccent.shade700;

class AuthorizedGroupPageScreen extends StatefulWidget {
  final AdvancedGroupInfo advancedGroupInfo;
  final int conversationID;
  final Function() needRefresh;

  const AuthorizedGroupPageScreen({
    Key key,
    @required this.advancedGroupInfo,
    @required this.conversationID,
    @required this.needRefresh,
  })  : assert(advancedGroupInfo != null),
        assert(needRefresh != null),
        super(key: key);

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

class _AuthorizedGroupPageScreenState
    extends SafeState<AuthorizedGroupPageScreen>
    with SingleTickerProviderStateMixin {
  AdvancedGroupInfo get _group => widget.advancedGroupInfo;

  TabController _tabController;

  List<_GroupPageTab> get _tabs => [
        // Posts list
        _GroupPageTab(
          widget: (c) => GroupPostsSection(group: _group),
          label: tr("Posts"),
        ),

        // About the group
        _GroupPageTab(
          widget: (c) => AboutGroupSection(group: _group),
          label: tr("About"),
        ),

        _GroupPageTab(
          widget: (c) => GroupMembersSection(groupID: _group.id),
          label: tr("Members"),
          visible: _group.isAtLeastModerator || _group.isMembersListPublic,
        )
      ].where((element) => element.visible).toList()

        // Add group conversations
        ..insertAll(
            1,
            _group.conversations
                .map((e) => _GroupPageTab(
                    widget: (c) => GroupConversationSection(conv: e),
                    label: e.name))
                .toList());

  @override
  void initState() {
    _tabController = TabController(
      length: _tabs.length,
      initialIndex: widget.conversationID == null
          ? 0
          : 1 +
              _group.conversations
                  .indexWhere((element) => element.id == widget.conversationID),
      vsync: this,
    );

    super.initState();
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PostContainer(
      child: Column(
        children: [
          _buildGroupPageHeader(),
          Row(
            children: [
              Expanded(
                child: Material(
                  color: _headerColor,
                  child: TabBar(
                    isScrollable: true,
                    tabs: _tabs.map((e) => e.tab).toList(),
                    controller: _tabController,
                  ),
                ),
              ),
            ],
          ),
          Expanded(
            child: TabBarView(
              controller: _tabController,
              children: _tabs.map((e) => e.widget(context)).toList(),
            ),
          ),
        ],
      ),
    );
  }

  /// Build group page header
  Widget _buildGroupPageHeader() {
    return Material(
      color: _headerColor,
      child: DefaultTextStyle(
        style: TextStyle(color: _headerTextColor),
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: <Widget>[
              GroupIcon(
                group: _group,
              ),
              Expanded(
                child: Text(
                  " ${_group.displayName}",
                  style: TextStyle(fontSize: 20),
                ),
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  GroupMembershipWidget(
                    group: _group,
                    onUpdated: () => widget.needRefresh(),
                  ),
                  Container(
                    height: 4,
                  ),
                  GroupFollowingWidget(
                    group: _group,
                    onUpdated: () => widget.needRefresh(),
                    inactiveColor: Colors.blueAccent,
                    activeColor: Colors.white,
                  ),
                  Container(
                    height: 2,
                  ),
                  LikeWidget(
                    inativeColor: Colors.blueAccent,
                    activeColor: Colors.white,
                    likeElement: _group,
                  ),
                ],
              ),

              // Settings button
              _group.isAdmin
                  ? IconButton(
                      icon: Icon(Icons.settings, color: _headerTextColor),
                      onPressed: () => MainController.of(context).push(
                          GroupSettingsScreen(groupID: _group.id),
                          canShowAsDialog: true))
                  : Container(),
            ],
          ),
        ),
      ),
    );
  }
}

class _GroupPageTab {
  final WidgetBuilder widget;
  final bool visible;
  final String label;

  const _GroupPageTab({
    @required this.widget,
    this.visible = true,
    @required this.label,
  })  : assert(widget != null),
        assert(visible != null),
        assert(label != null);

  Tab get tab => Tab(text: label);
}