define('bootstrap-form-validation', ['jquery'], function($) {
  return {
    resetValidation: function(formControl) {
      var formGroup = formControl.closest('.form-group');
      formGroup.removeClass('has-success has-error has-warning');
      formGroup.find('.form-control-feedback').addClass('hidden');
      formGroup.find('.help-block').addClass('hidden').empty();
    },
    setLoading: function(formControl) {
      this.resetValidation(formControl);
      formControl.closest('.form-group').find('.form-control-feedback.loading').removeClass('hidden');
    },
    setSuccess: function(formControl) {
      this.resetValidation(formControl);
      formControl.closest('.form-group').addClass('has-success').find('.form-control-feedback.success')
        .removeClass('hidden');
    },
    setError: function(formControl, message) {
      this.resetValidation(formControl);
      formControl.closest('.form-group').addClass('has-error')
        .find('.form-control-feedback.error').removeClass('hidden').end()
        .find('.help-block').removeClass('hidden').text(message);
    }
  };
});

//
// Group Creation
//
require(['jquery', 'bootstrap-form-validation'], function($, validation) {
  var createGroupModal = $('#createGroupModal');
  var createGroupButton = createGroupModal.find('button.btn-primary');
  createGroupModal.on('shown.bs.modal', function() {
    // Reset the form each time the modal is shown.
    createGroupModal.find('form').trigger('reset');
    createGroupModal.find('.form-control').each(function() {
      validation.resetValidation($(this));
    }).first().focus();
    createGroupButton.prop('disabled', true);
  });

  // Group name validation.
  var groupNameTimeout;
  var groupNameInput = createGroupModal.find('input[name="name"]');
  groupNameInput.on('input', function() {
    clearTimeout(groupNameTimeout);
    createGroupButton.prop('disabled', true);
    validation.resetValidation(groupNameInput);
    if (groupNameInput.val() !== '') {
      validation.setLoading(groupNameInput);
      groupNameTimeout = setTimeout(function() {
        var groupName = groupNameInput.val();
        var groupURL = new XWiki.Document(groupName, 'XWiki').getRestURL();
        $.get(groupURL).then(() => {
          // A document with the specified name already exists.
          var message = "__name__ cannot be used for the group name, as another page with this name already exists."
            .replace('__name__', groupName);
          validation.setError(groupNameInput, message);
        }).catch(response => {
          if (response.status === 404) {
            // The document does not exist, so we can use it.
            validation.setSuccess(groupNameInput);
            createGroupButton.prop('disabled', false);
          } else {
            // Something else happened. This was not intended.
            var message = "An error occurred while communicating with the server. Please check that the server is accessible, and you have the proper rights to perform the requested action.";
            validation.setError(groupNameInput, message);
          }
        });
      }, 500);
    }
  });

  createGroupModal.on('submit', function(event) {
    event.preventDefault();
    var data = createGroupModal.find('form').serializeArray();
    data.push({name: 'ajax', value: 1});
    var groupName = groupNameInput.val();
    var createGroupURL = new XWiki.Document(groupName, 'XWiki').getURL('save');
    // Disable the form to prevent it from being submitted twice.
    createGroupModal.find(':input').prop('disabled', true);
    var notification = new XWiki.widgets.Notification(
      "Creating the group...",
      'inprogress'
    );
    Promise.resolve($.post(createGroupURL, data)).then(function() {
      // Close the modal and refresh the groups live table.
      createGroupModal.modal('hide');
      window.livetable_groupstable.refresh();
      notification.replace(new XWiki.widgets.Notification(
        "Group created",
        'done'
      ));
    }).catch(function() {
      notification.replace(new XWiki.widgets.Notification(
        "Failed to create the group",
        'error'
      ));
    }).finally(function() {
      // Re-enable the form.
      createGroupModal.find(':input').prop('disabled', false);
    });
  });
});

//
// Scope Filtering
//
require(['jquery'], function($) {
  var options = $('#groupstable').prev('.tipfilters').remove().find('select[name="wiki"]').html();
  var scopeFilter = $('#groupstable .xwiki-livetable-display-filters select[name="scope"]')
  scopeFilter.attr('name', 'wiki').html(options);
});

//
// Live Table Modals
//

define('xwiki-livetable-modal', ['jquery', 'bootstrap'], function($) {
  $.fn.bindActionToModal = function(action, modal) {
    var actionToModal = action;
    if (typeof action === 'string') {
      var actionToModal = {};
      actionToModal[action] = modal;
    }
    return this.each(function() {
      var liveTableElement = $(this);
      var liveTable = window['livetable_' + liveTableElement.attr('id')];
      $.each(actionToModal, function(action, modal) {
        liveTableElement.on('click', 'a.action' + action, function(event) {
          event.preventDefault();
          var actionTrigger = $(this);
          var row = actionTrigger.closest('tr');
          var rowIndex = parseInt(row.attr('data-index'));
          $(modal).data({
            rowData: liveTable.fetchedRows[rowIndex],
            rowIndex: rowIndex,
            liveTable: liveTable,
            liveTableElement: liveTableElement
          }).modal('show');
        });
      });
    });
  };

  $('.modal[data-liveTable]').each(function() {
    var modal = $(this);
    $(modal.attr('data-liveTable')).bindActionToModal(modal.attr('data-liveTableAction'), modal);
  });
});

require(['jquery', 'xwiki-meta', 'xwiki-livetable-modal'], function($, xm) {
  //
  // Group Editing
  //
  var editGroupModal = $('#editGroupModal');
  editGroupModal.on('show.bs.modal', function() {
    var rowData = editGroupModal.data('rowData');
    var groupReference = XWiki.Model.resolve(rowData.doc_fullName, XWiki.EntityType.DOCUMENT, [rowData.doc_wiki]);
    var groupDocument = new XWiki.Document(groupReference);
    var editGroupURL = groupDocument.getURL('edit', 'xpage=plain');
    editGroupModal.find('.modal-body').empty().addClass('loading').load(editGroupURL, function() {
      $(this).removeClass('loading');
      $(document).trigger('xwiki:dom:updated', {'elements': $(this).toArray()});
    });
  }).on('hide.bs.modal', function() {
    editGroupModal.data('liveTable').refresh();
  });

  //
  // Group Deletion
  //
  var deleteGroupModal = $('#deleteGroupModal');
  deleteGroupModal.on('show.bs.modal', function() {
    var rowData = deleteGroupModal.data('rowData');
    var groupReference = rowData.doc_fullName;
    if (XWiki.currentWiki !== rowData.doc_wiki) {
      groupReference = XWiki.Model.resolve(groupReference, XWiki.EntityType.DOCUMENT, [rowData.doc_wiki]);
      groupReference = XWiki.Model.serialize(groupReference);
    }
    deleteGroupModal.find('.groupName').text(groupReference);
  }).find('.btn-danger').on('click', function() {
    var notification = new XWiki.widgets.Notification(
      "Deleting the group...",
      'inprogress'
    );
    $.post('', {
      xpage: 'deleteuorg',
      docname: deleteGroupModal.find('.groupName').text(),
      form_token: xm.form_token
    }).then(() => {
      deleteGroupModal.data('liveTable').deleteRow(deleteGroupModal.data('rowIndex'));
      notification.replace(new XWiki.widgets.Notification(
        "Group deleted",
        'done'
      ));
    }).catch(() => {
      notification.replace(new XWiki.widgets.Notification(
        "Failed to delete the group",
        'error'
      ));
    });
  });
});
