function initializeGroupView() {
  $.ajax({
    method: "GET",
    url: window.CRM.root + "/api/groups/" + window.CRM.currentGroup + "/roles",
    dataType: "json",
  }).then(function (data) {
    window.CRM.groupRoles = data ?? [];
    $("#newRoleSelection").select2({
      data: window.CRM.groupRoles.map((groupRole) => {
        return {
          id: groupRole.OptionId,
          // i18next-disable-next-line
          text: i18next.t(groupRole.OptionName),
        };
      }),
    });
    initDataTable();
    //echo '<option value="' . $role['lst_OptionID'] . '">' . $role['lst_OptionName'] . '</option>';
  });

  $(".personSearch").select2({
    minimumInputLength: 2,
    language: window.CRM.shortLocale,
    ajax: {
      url: function (params) {
        return window.CRM.root + "/api/persons/search/" + params.term;
      },
      dataType: "json",
      delay: 250,
      data: function (params) {
        return {
          q: params.term, // search term
          page: params.page,
        };
      },
      processResults: function (rdata, page) {
        return { results: rdata };
      },
      cache: true,
    },
  });

  $(".personSearch").on("select2:select", function (e) {
    window.CRM.groups.promptSelection(
      {
        Type: window.CRM.groups.selectTypes.Role,
        GroupID: window.CRM.currentGroup,
      },
      function (selection) {
        window.CRM.groups.addPerson(window.CRM.currentGroup, e.params.data.objid, selection.RoleID).then(function () {
          $(".personSearch").val(null).trigger("change");
          window.CRM.DataTableAPI.ajax.reload(); /* we reload the data no need to add the person inside the dataTable */
        });
      },
    );
  });

  $("#deleteSelectedRows").on("click", function () {
    var deletedRows = window.CRM.DataTableAPI.rows(".selected").data().toArray();
    bootbox.confirm({
      message:
        i18next.t("Are you sure you want to remove the selected group members?") + " (" + deletedRows.length + ") ",
      buttons: {
        confirm: {
          label: i18next.t("Delete"),
          className: "btn-danger",
        },
        cancel: {
          label: i18next.t("No"),
          className: "btn-default",
        },
      },
      callback: function (result) {
        if (result) {
          deletedRows.forEach(function (value, index) {
            window.CRM.groups.removePerson(window.CRM.currentGroup, value.PersonId).then(function () {
              var dataTableAPI = window.CRM.DataTableAPI;
              dataTableAPI
                .row(function (idx, data, node) {
                  if (data.PersonId == value.PersonId) {
                    return true;
                  }
                })
                .remove();
              dataTableAPI.rows().invalidate().draw(true);
            });
          });
        }
      },
    });
  });

  $("#addSelectedToCart").on("click", function () {
    if (window.CRM.DataTableAPI.rows(".selected").length > 0) {
      var selectedPersons = {
        Persons: window.CRM.DataTableAPI.rows(".selected")
          .data()
          .toArray()
          .map(function (val, i) {
            return val.PersonId;
          }),
      };
      window.CRM.cartManager.addPerson(selectedPersons.Persons, {
        showNotification: true,
      });
    }
  });

  //copy membership
  $("#addSelectedToGroup").on("click", function () {
    window.CRM.groups.promptSelection(
      {
        Type: window.CRM.groups.selectTypes.Group | window.CRM.groups.selectTypes.Role,
      },
      function (data) {
        selectedRows = window.CRM.DataTableAPI.rows(".selected").data().toArray();
        selectedRows.forEach(function (row) {
          window.CRM.groups.addPerson(data.GroupID, row.PersonId, data.RoleID);
        });
      },
    );
  });

  $("#moveSelectedToGroup").on("click", function () {
    window.CRM.groups.promptSelection(
      {
        Type: window.CRM.groups.selectTypes.Group | window.CRM.groups.selectTypes.Role,
      },
      function (data) {
        selectedRows = window.CRM.DataTableAPI.rows(".selected").data().toArray();
        selectedRows.forEach(function (value, index) {
          window.CRM.groups.addPerson(data.GroupID, value.PersonId, data.RoleID);

          window.CRM.groups.removePerson(window.CRM.currentGroup, value.PersonId).then(function () {
            var dataTableAPI = window.CRM.DataTableAPI;
            dataTableAPI
              .row(function (idx, data, node) {
                if (data.PersonId == value.PersonId) {
                  return true;
                }
              })
              .remove();
            dataTableAPI.rows().invalidate().draw(true);
          });
        });
      },
    );
  });

  $("#AddGroupMembersToCart").on("click", function () {
    window.CRM.cartManager.addGroup($(this).data("groupid"), {
      showNotification: true,
    });
  });

  $(document).on("click", ".view-person-photo", function (e) {
    var personId = $(e.currentTarget).data("person-id");
    window.CRM.showPhotoLightbox("person", personId);
    e.stopPropagation();
  });

  $(document).on("click", ".changeMembership", function (e) {
    var PersonID = $(e.currentTarget).data("personid");
    window.CRM.groups.promptSelection(
      {
        Type: window.CRM.groups.selectTypes.Role,
        GroupID: window.CRM.currentGroup,
      },
      function (selection) {
        window.CRM.groups.addPerson(window.CRM.currentGroup, PersonID, selection.RoleID).done(function () {
          window.CRM.DataTableAPI.row(function (idx, data, node) {
            if (data.PersonId == PersonID) {
              data.RoleId = selection.RoleID;
              return true;
            }
          });
          window.CRM.DataTableAPI.rows().invalidate().draw(true);
        });
      },
    );
    e.stopPropagation();
  });
}

// Wait for locales to load before initializing
$(document).ready(function () {
  window.CRM.onLocalesReady(initializeGroupView);
});

function initDataTable() {
  var DataTableOpts = {
    ajax: {
      url: window.CRM.root + "/api/groups/" + window.CRM.currentGroup + "/members",
      dataSrc: "Person2group2roleP2g2rs",
    },
    columns: [
      {
        width: "auto",
        title: i18next.t("Name"),
        data: "PersonId",
        render: function (data, type, full, meta) {
          var photoIcon = "";
          if (full.Person.HasPhoto) {
            photoIcon =
              ' <button class="btn btn-xs btn-outline-secondary view-person-photo" data-person-id="' +
              full.PersonId +
              '" title="' +
              i18next.t("View Photo") +
              '">' +
              '<i class="fa-solid fa-camera"></i>' +
              "</button>";
          }
          // Escape full name to prevent XSS
          const escapedName = $("<div>").text(full.Person.FullName).html();
          return (
            '<a target="_top" href="PersonView.php?PersonID=' + full.PersonId + '">' + escapedName + "</a>" + photoIcon
          );
        },
      },
      {
        width: "15%",
        title: i18next.t("Group Role"),
        data: "RoleId",
        render: function (data, type, full, meta) {
          thisRole = $(window.CRM.groupRoles).filter(function (index, item) {
            return item.OptionId == data;
          })[0];
          // Escape role name to prevent XSS
          // i18next-disable-next-line
          const escapedRoleName = $("<div>").text(i18next.t(thisRole?.OptionName)).html();
          return (
            '<span class="d-inline-block text-truncate" style="max-width: 150px;" title="' +
            escapedRoleName +
            '">' +
            escapedRoleName +
            "</span> " +
            '<button class="btn btn-xs changeMembership" data-personid=' +
            full.PersonId +
            '><i class="fa-solid fa-pen"></i></button>'
          );
        },
      },
      {
        width: "20%",
        title: i18next.t("Address"),
        data: null,
        render: function (data, type, full, meta) {
          var address = full.Person.Address1;
          if (full.Person.Address2) {
            address += " " + full.Person.Address2;
          }
          // Escape address to prevent XSS
          const escapedAddress = $("<div>").text(address).html();
          return (
            '<span class="d-inline-block text-truncate" style="max-width: 200px;" title="' +
            escapedAddress +
            '">' +
            escapedAddress +
            "</span>"
          );
        },
      },
      {
        width: "10%",
        title: i18next.t("City"),
        data: "Person.City",
      },
      {
        width: "8%",
        title: i18next.t("State"),
        data: "Person.State",
      },
      {
        width: "8%",
        title: i18next.t("Zip Code"),
        data: "Person.Zip",
      },
      {
        width: "12%",
        title: i18next.t("Cell Phone"),
        data: "Person.CellPhone",
      },
      {
        width: "15%",
        title: i18next.t("Email"),
        data: "Person.Email",
        render: function (data, type, full, meta) {
          if (data) {
            // Escape email to prevent XSS
            const escapedEmail = $("<div>").text(data).html();
            return (
              '<span class="d-inline-block text-truncate" style="max-width: 180px;" title="' +
              escapedEmail +
              '">' +
              escapedEmail +
              "</span>"
            );
          }
          return "";
        },
      },
    ],
    responsive: true,
    autoWidth: false,
    drawCallback: function (settings) {
      var api = new $.fn.dataTable.Api(settings);
      var totalMembers = api.rows({ search: "none" }).count();
      $("#iTotalMembers").text(totalMembers);
    },
    createdRow: function (row, data, index) {
      $(row).addClass("groupRow");
    },
  };
  $.extend(DataTableOpts, window.CRM.plugin.dataTable);
  window.CRM.DataTableAPI = $("#membersTable").DataTable(DataTableOpts);

  $("#isGroupActive").change(function () {
    $.ajax({
      type: "POST", // define the type of HTTP verb we want to use (POST for our form)
      url: window.CRM.root + "/api/groups/" + window.CRM.currentGroup + "/settings/active/" + $(this).prop("checked"),
      dataType: "json", // what type of data do we expect back from the server
      encode: true,
    });
  });

  $("#isGroupEmailExport").change(function () {
    $.ajax({
      type: "POST", // define the type of HTTP verb we want to use (POST for our form)
      url:
        window.CRM.root +
        "/api/groups/" +
        window.CRM.currentGroup +
        "/settings/email/export/" +
        $(this).prop("checked"),
      dataType: "json", // what type of data do we expect back from the server
      encode: true,
    });
  });

  $(document).on("click", ".groupRow", function () {
    $(this).toggleClass("selected");
    var selectedRows = window.CRM.DataTableAPI.rows(".selected").data().length;
    $("#deleteSelectedRows").prop("disabled", !selectedRows);
    $("#deleteSelectedRows").text(i18next.t("Remove") + " (" + selectedRows + ") " + i18next.t("Members from group"));
    $("#buttonDropdown").prop("disabled", !selectedRows);
    $("#addSelectedToGroup").prop("disabled", !selectedRows);
    $("#addSelectedToGroup").html(
      i18next.t("Add") + "  (" + selectedRows + ") " + i18next.t("Members to another group"),
    );
    $("#addSelectedToCart").prop("disabled", !selectedRows);
    $("#addSelectedToCart").html(i18next.t("Add") + "  (" + selectedRows + ") " + i18next.t("Members to cart"));
    $("#moveSelectedToGroup").prop("disabled", !selectedRows);
    $("#moveSelectedToGroup").html(
      i18next.t("Move") + "  (" + selectedRows + ") " + i18next.t("Members to another group"),
    );
  });
}
