class UserEntry {
    constructor(username, isMember, rowElement) {
        this.username = username;
        this.isMember = isMember;
        this.rowElement = rowElement;
        this.buttonElement = $(rowElement).find(".toggleMembershipButton");
        if (isMember) {
            $(this.buttonElement).click(() => this.onClickLeave());
        } else {
            $(this.buttonElement).click(() => this.onClickJoin());
        }
    }

    onClickLeave() {
        this.setButtonAppearanceInProgress();
        $.ajax({
            context: {
                "userEntry": this
            },
            url: `/api/group/${groupname}/member/${this.username}`,
            type: "DELETE",
            dataType: "json",
        }).done(function() {
            this.userEntry.isMember = false;
            $(this.userEntry.buttonElement).off("click");
            $(this.userEntry.buttonElement).click(() => this.userEntry.onClickJoin());
            $(this.userEntry.rowElement).prependTo($("#tableNonMembers").find("tbody"));
            this.userEntry.setButtonAppearanceJoinGroup();
        }).fail(function(xhr, status, errorThrown) {
            console.log(`Error: ${errorThrown}`);
            console.log(`Status: ${status}`);
            showErrorMessage(xhr.responseJSON['message']);
            this.userEntry.setButtonAppearanceLeaveGroup();
        });
    }

    onClickJoin() {
        this.setButtonAppearanceInProgress();
        $.ajax({
            context: {
                "userEntry": this
            },
            url: `/api/group/${groupname}/member/${this.username}`,
            type: "POST",
            dataType: "json",
        }).done(function() {
            this.userEntry.isMember = true;
            $(this.userEntry.buttonElement).off("click");
            $(this.userEntry.buttonElement).click(() => this.userEntry.onClickLeave());
            $(this.userEntry.rowElement).prependTo($("#tableMembers").find("tbody"));
            this.userEntry.setButtonAppearanceLeaveGroup();
        }).fail(function(xhr, status, errorThrown) {
            console.log(`Error: ${errorThrown}`);
            console.log(`Status: ${status}`);
            showErrorMessage(xhr.responseJSON['message']);
            this.userEntry.setButtonAppearanceJoinGroup();
        });
    }

    setButtonAppearanceInProgress() {
        this.buttonElement.removeClass("btn-danger btn-success btn-secondary");
        this.buttonElement.addClass("btn-secondary");
        this.buttonElement.empty();
        this.buttonElement.html(
            '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>' + 
            '<span> Loading...</span>'
        );
        this.buttonElement.prop("disabled", true);
    }

    setButtonAppearanceLeaveGroup() {
        this.buttonElement.removeClass("btn-danger btn-success btn-secondary");
        this.buttonElement.addClass("btn-danger");
        this.buttonElement.empty();
        this.buttonElement.html(
            '<i class="bi-person-fill-dash"></i> Remove'
        );
        this.buttonElement.prop("disabled", false);
    }

    setButtonAppearanceJoinGroup() {
        this.buttonElement.removeClass("btn-danger btn-success btn-secondary");
        this.buttonElement.addClass("btn-success");
        this.buttonElement.empty();
        this.buttonElement.html(
            '<i class="bi-person-fill-add"></i> Add'
        );
        this.buttonElement.prop("disabled", false);
    }
}

function showErrorMessage(message) {
    $("nav").after([
    '<div class="alert alert-danger alert-dismissible" role="alert">',
        `<div>${message}</div>`,
        '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
    '</div>'
    ].join(''));
}

function getUserEntries() {
    let userEntries = [];

    // Construct member entries
    for (let entry of membersTable.find("tbody").find(".userEntry")) {
        userEntries.push(new UserEntry(
            entry.id,
            true,
            entry
        ));
    }

    // Construct nonmember entries
    for (let entry of nonMembersTable.find("tbody").find(".userEntry")) {
        userEntries.push(new UserEntry(
            entry.id,
            false,
            entry
        ));
    }

    return userEntries;
}

let nonMembersTable = undefined;
let membersTable = undefined;
let entries = undefined;
const groupname = window.location.pathname.split("/").pop();

$(document).ready(function() {
    nonMembersTable = $("#tableNonMembers");
    membersTable = $("#tableMembers");
    entries = getUserEntries();
});
