import 'package:comunic/enums/post_target.dart';
import 'package:comunic/helpers/posts_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/models/advanced_user_info.dart';
import 'package:comunic/ui/routes/main_route.dart';
import 'package:comunic/ui/widgets/account_image_widget.dart';
import 'package:comunic/ui/widgets/post_create_form_widget.dart';
import 'package:comunic/ui/widgets/posts_list_widget.dart';
import 'package:comunic/ui/widgets/scroll_watcher.dart';
import 'package:comunic/utils/conversations_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';

/// User page route
///
/// @author Pierre HUBERT

enum _PageStatus { LOADING, ERROR, READY }

enum _MenuOptions { FRIENDS_LIST }

class UserPageScreen extends StatefulWidget {
  final int userID;

  const UserPageScreen({Key key, @required this.userID})
      : assert(userID != null),
        super(key: key);

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

class _UserPageScreenState extends State<UserPageScreen> {
  // Helpers
  final usersHelper = UsersHelper();
  final PostsHelper _postsHelper = PostsHelper();

  // Objects members
  _PageStatus _status = _PageStatus.LOADING;
  AdvancedUserInfo _userInfo;
  GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
      GlobalKey<RefreshIndicatorState>();

  // Scroll detection (to load more user posts automatically)
  final _postListKey = GlobalKey<PostsListWidgetState>();
  ScrollWatcher _scrollWatcher;

  _setStatus(_PageStatus s) => setState(() => _status = s);

  @override
  void initState() {
    _scrollWatcher = ScrollWatcher(
        onReachBottom: () => _postListKey.currentState.reachedPostsBottom());
    super.initState();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _getUserInfo();
  }

  Future<void> _getUserInfo() async {
    _setStatus(_PageStatus.LOADING);

    try {
      final user = await usersHelper.getAdvancedInfo(widget.userID);

      setState(() {
        _userInfo = user;
      });

      _setStatus(_PageStatus.READY);
    } on GetUserAdvancedUserError catch (e) {
      _setStatus(_PageStatus.ERROR);

      if (e.cause == GetUserAdvancedInformationErrorCause.NOT_AUTHORIZED) {
        final controller = MainController.of(context);
        controller.popPage();
        controller.openUserAccessDeniedPage(widget.userID);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_status == _PageStatus.LOADING) return buildLoadingPage();

    if (_status == _PageStatus.ERROR) return _buildError();

    return Scaffold(
      body: RefreshIndicator(
        key: _refreshIndicatorKey,
        child: ListView(
          children: <Widget>[]
            ..add(_buildHeader())
            ..addAll(_buildBody()),
          physics: AlwaysScrollableScrollPhysics(),
          controller: _scrollWatcher,
        ),
        onRefresh: _getUserInfo,
      ),
    );
  }

  /// Error card
  Widget _buildError() {
    return Scaffold(
      appBar: AppBar(
        title: Text(tr("Error")),
      ),
      body: Center(
          child:
              buildErrorCard(tr("Could not get user information!"), actions: [
        FlatButton(
          onPressed: _getUserInfo,
          child: Text(
            tr("Retry").toUpperCase(),
            style: TextStyle(color: Colors.white),
          ),
        )
      ])),
    );
  }

  Widget _buildHeader() {
    return Container(
      color: Colors.black26,
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          children: <Widget>[
            AccountImageWidget(user: _userInfo),
            Text(" ${_userInfo.displayName}"),
            Spacer(),
            IconButton(
                icon: Icon(
                  Icons.chat,
                ),
                onPressed: () {
                  openPrivateConversation(context, widget.userID);
                }),
            PopupMenuButton<_MenuOptions>(
              itemBuilder: (c) => [
                PopupMenuItem(
                  child: Text(tr("Friends")),
                  enabled: _userInfo != null,
                  value: _MenuOptions.FRIENDS_LIST,
                )
              ],
              onSelected: _selectedMenuOption,
            ),
          ],
        ),
      ),
    );
  }

  List<Widget> _buildBody() {
    return <Widget>[
      // Posts create form
      _userInfo.canPostTexts
          ? PostCreateFormWidget(
              postTarget: PostTarget.USER_PAGE,
              targetID: _userInfo.id,
              onCreated: _postCreated,
            )
          : Container(),

      // Posts list
      PostsListWidget(
        key: _postListKey,
        getPostsList: () => _postsHelper.getUserPosts(widget.userID),
        getOlder: (from) =>
            _postsHelper.getUserPosts(widget.userID, from: from),
        showPostsTarget: false,
        buildListView: false,
      ),
    ];
  }

  /// Method called each time a menu option is selected
  void _selectedMenuOption(_MenuOptions value) {
    switch (value) {
      case _MenuOptions.FRIENDS_LIST:
        MainController.of(context).openUserFriendsList(_userInfo.id);
        break;
    }
  }

  /// Method called once a post has been created
  void _postCreated() {
    _refreshIndicatorKey.currentState.show();
  }
}