import 'package:comunic/helpers/conversations_helper.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/user.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/tiles/simple_user_tile.dart';
import 'package:comunic/ui/widgets/pick_user_widget.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart';

/// Create / Update conversation screen
///
/// @author Pierre HUBERT

enum _MembersMenuChoices { REMOVE }

class UpdateConversationScreen extends StatefulWidget {
  final Conversation initialSettings;
  final UsersList initialUsers;

  const UpdateConversationScreen({
    Key key,
    this.initialSettings,
    this.initialUsers,
  }) : super(key: key);

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

class _UpdateConversationScreen extends State<UpdateConversationScreen> {
  TextEditingController _nameController = TextEditingController();
  UsersList _members = UsersList();
  bool _followConversation = true;
  bool _canEveryoneAddMembers = true;

  get isUpdating => widget.initialSettings != null;

  get isOwner => !isUpdating || widget.initialSettings.isOwner;

  Conversation get _initialSettings => widget.initialSettings;

  bool get _canAddMembers => isOwner || _initialSettings.canEveryoneAddMembers;

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

    // Check if we are updating an existing conversation
    if (widget.initialSettings != null) {
      _nameController.text = widget.initialSettings.name;
      _members = widget.initialUsers;
      _followConversation = widget.initialSettings.following;
      _canEveryoneAddMembers = widget.initialSettings.canEveryoneAddMembers;
    }
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Container(
        padding: EdgeInsets.all(8.0),
        child: Column(
          children: <Widget>[
            // Conversation name
            TextField(
              controller: _nameController,
              decoration: InputDecoration(
                labelText: tr("Conversation name (optionnal)"),
                alignLabelWithHint: true,
                enabled: isOwner,
              ),
            ),

            // Follow conversation ?
            Row(
              children: <Widget>[
                Switch.adaptive(
                  value: _followConversation,
                  onChanged: (b) => setState(() {
                    _followConversation = b;
                  }),
                ),
                Text(tr("Follow conversation"))
              ],
            ),

            // Allow every members of the conversation to add users ?
            Row(
              children: <Widget>[
                Switch.adaptive(
                  value: _canEveryoneAddMembers,
                  onChanged: isOwner
                      ? (b) => setState(() {
                            _canEveryoneAddMembers = b;
                          })
                      : null,
                ),
                Text(tr("Allow all members of the conversation to add users"))
              ],
            ),

            // Add a member to the conversation
            PickUserWidget(
              resetOnChoose: true,
              keepFocusOnChoose: true,
              label: tr("Add member"),
              enabled: _canAddMembers,
              onSelectUser: (user) => setState(() {
                if (!_members.contains(user)) _members.insert(0, user);
              }),
            ),

            //Conversation members
            Column(
              children: _members
                  .map((f) => SimpleUserTile(
                        user: f,
                        trailing: _canAddMembers
                            ? PopupMenuButton<_MembersMenuChoices>(
                                captureInheritedThemes: false,
                                onSelected: (choice) =>
                                    _membersMenuItemSelected(f, choice),
                                itemBuilder: (c) =>
                                    <PopupMenuEntry<_MembersMenuChoices>>[
                                  PopupMenuItem(
                                    child: Text(tr("Remove")),
                                    value: _MembersMenuChoices.REMOVE,
                                    enabled: isOwner ||
                                        (_canEveryoneAddMembers &&
                                            !_initialSettings.members
                                                .contains(f.id)),
                                  )
                                ],
                              )
                            : null,
                      ))
                  .toList(),
            ),

            // Submit button
            RaisedButton(
              onPressed: _members.length < 1 ? null : _submitForm,
              child: Text(isUpdating
                  ? tr("Update the conversation")
                  : tr("Create the conversation")),
            )
          ],
        ),
      ),
    );
  }

  /// An option of the members menu has been selected
  void _membersMenuItemSelected(User user, _MembersMenuChoices choice) {
    if (choice == null) return;

    if (choice == _MembersMenuChoices.REMOVE)
      setState(() {
        _members.removeWhere((u) => u.id == user.id);
      });
  }

  /// Submit the conversation
  Future<void> _submitForm() async {
    final settings = Conversation(
        id: isUpdating ? widget.initialSettings.id : 0,
        ownerID: isUpdating ? widget.initialSettings.ownerID : 0,
        name: _nameController.text,
        following: _followConversation,
        members: _members.usersID,
        canEveryoneAddMembers: _canEveryoneAddMembers,

        // Give random value to these fields as they are ignored here
        lastActive: 0,
        sawLastMessage: true);

    // Create the conversation
    var conversationID = settings.id;
    bool error = false;
    if (isUpdating)
      error = !(await ConversationsHelper().updateConversation(settings));
    else {
      conversationID = await ConversationsHelper().createConversation(settings);
      if (conversationID < 1) error = true;
    }

    // Check for errors
    if (error)
      return Scaffold.of(context).showSnackBar(SnackBar(
        content: Text(isUpdating
            ? tr("Could not update the conversation!")
            : tr("Could not create the conversation!")),
        duration: Duration(seconds: 1),
      ));

    // Open the conversation

    MainController.of(context).popPage();
    if (!isUpdating)
      MainController.of(context).openConversation(conversationID);
  }
}