import 'package:comunic/helpers/conversations_helper.dart';
import 'package:comunic/helpers/events_helper.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/ui/dialogs/screen_dialog.dart';
import 'package:comunic/ui/screens/conversation_members_screen.dart';
import 'package:comunic/ui/screens/conversation_screen.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/ui/widgets/tablet_mode/conversations/conversation_window_container.dart';
import 'package:comunic/utils/account_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';

/// Single conversation window
///
/// @author Pierre Hubert

enum _Actions { OPEN_MEMBERS }

class ConversationWindow extends StatefulWidget {
  final int convID;
  final Function() onClose;

  const ConversationWindow({
    Key key,
    @required this.convID,
    @required this.onClose,
  })  : assert(convID != null),
        assert(onClose != null),
        super(key: key);

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

class _ConversationWindowState extends SafeState<ConversationWindow> {
  Conversation _conversation;
  String _convTitle;
  bool _error = false;
  bool _collapsed = false;
  bool _hasNewMessages = false;

  int get _convID => widget.convID;

  final _convKey = UniqueKey();

  void _setError(bool e) => setState(() => _error = e);

  void _toggleVisibility() => setState(() {
        _collapsed = !_collapsed;
        if (!_collapsed) _hasNewMessages = false;
      });

  Future<void> _refresh() async {
    try {
      _setError(false);

      final conversation =
          await ConversationsHelper().getSingle(_convID, force: true);
      assert(conversation != null);
      final name =
          await ConversationsHelper.getConversationNameAsync(conversation);
      assert(name != null);

      setState(() {
        _conversation = conversation;
        _convTitle = name;
      });
    } catch (e, s) {
      _setError(true);
      print("Could not refresh the list of conversations! $e\n$s");
      showSimpleSnack(context, tr("Could not load conversation information!"));
    }
  }

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

    listen<NewConversationMessageEvent>((e) {
      if (e.msg.conversationID == _convID &&
          _collapsed &&
          e.msg.userID != userID()) setState(() => _hasNewMessages = true);
    });
  }

  @override
  Widget build(BuildContext context) {
    // In case of error
    if (_error)
      return ConversationWindowContainer(
        icon: Icon(Icons.error),
        title: Text(tr("Error")),
        onClose: widget.onClose,
        onToggleCollapse: _toggleVisibility,
        isCollapsed: _collapsed,
        body: buildErrorCard(tr("Could not load conversation information!"),
            actions: [
              FlatButton(
                textColor: Colors.white,
                onPressed: _refresh,
                child: Text(tr("Try again").toUpperCase()),
              )
            ]),
      );

    // If it is still loading
    if (_conversation == null)
      return ConversationWindowContainer(
        icon: Icon(Icons.message),
        title: Text(tr("Loading...")),
        onClose: widget.onClose,
        onToggleCollapse: _toggleVisibility,
        isCollapsed: _collapsed,
        body: buildCenteredProgressBar(),
      );

    return ConversationWindowContainer(
      icon: Icon(_hasNewMessages ? Icons.trip_origin : Icons.comment),
      appBarBgColor: _hasNewMessages ? Colors.green : null,
      title: Text(_convTitle),
      onClose: widget.onClose,
      onToggleCollapse: _toggleVisibility,
      isCollapsed: _collapsed,
      action: <Widget>[
        PopupMenuButton<_Actions>(
          itemBuilder: (c) => [
            // Show the list of members
            PopupMenuItem(
              child: Text(tr("Members")),
              value: _Actions.OPEN_MEMBERS,
            )
          ],
          onSelected: _menuCallback,
        ),
      ],
      body: ConversationScreen(
        key: _convKey,
        conversationID: _convID,
      ),
    );
  }

  void _menuCallback(_Actions value) {
    switch (value) {
      case _Actions.OPEN_MEMBERS:
        _openMembersList();
        break;
    }
  }

  void _openMembersList() {
    showScreenDialog(context, ConversationMembersScreen(convID: _convID));
  }
}