jQuery.expr[':'].icontains = function(a, i, m) {
    return jQuery(a).text().toUpperCase()
        .indexOf(m[3].toUpperCase()) >= 0;
};

const findByKey = (array, key, value) => {
    return array.find(item => item[key] === value);
}

var globalTeamsList = [];
var globalSectionsList = [];
var globalAnglersList = [];

$(document).ready(() => {

    teamsLoading(true);  // show the loading icon

    // Search functionality
    var searchTimeout = null;

    // Bind searching to when a key is lifted on the searchbar
    $("#search").keyup(() => {
        clearTimeout(searchTimeout);
        teamsLoading(true);

        searchTimeout = setTimeout(() => {
            fetchAndLoadTeams(...getFilters());
        }, 500)
    });

    // Bind searching to the search button
    $("#searchButton").on("click", () => {
        fetchAndLoadTeams(...getFilters());
    });

    // Bind searching to the sort buttons
    $("#sortForm input").on("click", function() {
        const name = $(this).attr("name");
        localStorage.setItem(name, $(`input[name='${name}']:checked`, "#sortForm").val());

        fetchAndLoadPageData();
    });

    // Load the last saved sort settings TODO: use local storage so it only saves on one reload
    const sortTeamsValue = localStorage.getItem("sortGroups");
    if (sortTeamsValue !== null) {
        $("#sortForm input[name='sortGroups']").val([sortTeamsValue]);
    }

    const sortMembersValue = localStorage.getItem("sortMembers");
    if (sortMembersValue !== null) {
        $("#sortForm input[name='sortMembers']").val([sortMembersValue]);
    }

    // Customize form validation for the edit members form
    $("#editMemberForm").validate({ errorClass: "text-danger mb-2" });

    // Prevent dropdowns from closing when clicking inside
    $('.dropdown-menu').on('hide.bs.dropdown', function (e) {
        var target = $(e.clickEvent.target);
        if(target.hasClass("keepopen") || target.parents(".keepopen").length){
            return false; // returning false should stop the dropdown from hiding.
        }else{
            return true;
        }
    });

    $("#editSectionNameButton").on("click", () => {

        $.ajax({
            url: getNextIdentifierUrl,
            type: "post",
            data: {
                "csrfmiddlewaretoken": csrfMiddlewareToken,
                "item": "section_name"
            },
            error: (xhr, textStatus, errorThrown) => { alert(xhr + " " + textStatus + " " + errorThrown); },
            success: (result) => {
                $("#editSectionName").val(result.identifier)
            }
        });

    });

    $("#editTeamNumberButton").on("click", () => {

        $.ajax({
            url: getNextIdentifierUrl,
            type: "post",
            data: {
                "csrfmiddlewaretoken": csrfMiddlewareToken,
                "item": "team_number"
            },
            error: (xhr, textStatus, errorThrown) => { alert(xhr + " " + textStatus + " " + errorThrown); },
            success: (result) => {
                $("#editTeamNumber").val(result.identifier)
            }
        });
    });

    $("select").select2({theme: "bootstrap-5", minimumResultsForSearch: -1})

    // load the teams with default filters
    fetchAndLoadPageData();

    // fetchAndLoadTeams(...getFilters());

});

/**
 * Returns an array of search filters in this order [search, sortTeams, sortMembers]
 * 
 * @returns {Array} The array of filters, each filter is a string.
 */
function getFilters() {
    return [
        $("#search").val(),
        $("input[name='sortGroups']:checked", "#sortForm").val(),
        $("input[name='sortMembers']:checked", "#sortForm").val()
    ]
}

function loadTeams(groups, highlightText="", groupType) {
    $("#teamsContainer").html("");  // Clear the previous listed teams

    if (groups.length < 1) {
        $("#teamsNotFound").show();
    }

    groupType = groupType.toUpperCase();

    // Iterate over and add each team
    groups.forEach((group) => {
        const oppositeGroupType = groupType === "SECTION"? "Team" : "Section";

        $("#teamsContainer").append(
            `<div class='col-12 col-md-6 col-xl-4 mb-4'>
                <div
                    class='${groupType.toLowerCase()} px-4 py-3 bg-body-tertiary bg-gradient rounded h-100 fluid-hover-zoom shadow-sm md-shadow-on-hover'
                    data-number='${group.name}'>
                    <h3>
                        <span class='fs-4'>
                            <span class='fs-6'>${groupType}</span> 
                            ${group.name}
                        </span>
                        <button class='btn btn-sm btn-light float-end border-0 me-1'>
                            <i class='bi bi-gear fs-6'></i>
                        </button>
                    </h3>
                    <ul class='list-unstyled team-members mt-3'>
                    </ul>
                </div>
            </div>`
        );

        // While we have the team, iterate over and add it's members
        group.members.forEach((member) => {
            const fullname = member.first + " " + member.last;
            
            const oppositeGroupName  = groupType === "SECTION"? member.team : member.section;

            $("#teamsContainer").find(".team-members").last().append(
                `<li class='mb-3 rounded w-100 fluid-hover-zoom'>
                    <div 
                        class='team-member d-flex'
                        data-first='${member.first}'
                        data-last='${member.last}'
                        data-member-id='${member.id}'
                        data-team-number='${member.team}'
                        data-peg-number='${member.peg}'
                        data-section='${member.section}'>
                        <div class='px-3 py-2 w-100'>
                            <div class='badge bg-secondary-subtle text-body fixed-badge' data-bs-title='Peg ${member.peg}' data-bs-toggle='tooltip'>
                                ${member.peg}
                            </div>
                            <div class='badge bg-secondary-subtle text-body fixed-badge' data-bs-title='${oppositeGroupType} ${oppositeGroupName}' data-bs-toggle='tooltip'>
                                ${oppositeGroupName}
                            </div>
                            <div class='d-inline-block ms-2 team-member-fullname'>
                                ${fullname}
                            </div>
                        </div>
                        <button type='button' class='ms-auto btn btn-light border-0 fs-6 pencil-btn align-self-center me-1 force-contents-center'>
                            <i class='bi bi-pencil'></i>
                        </button>
                    </div>
                </li>`
            )
        });
    });

    activateTooltips();  // activate the new tooltips

    // Highlight all instances where the text matches the search critera
    if (!isEmptyOrSpaces(highlightText)) {
        $("#teamsContainer").find('.team-member-fullname').each(function() {
            var regex = new RegExp(highlightText, 'gi');
            $(this).html($(this).text().replace(regex, '<span class="text-company fw-bolder border-2 border-bottom border-company">$&</span>'));
        });
    }
    
    // Bind edit team modal to the edit team button
    $(".team > h3 > button").on("click", function() {
        $(this).addClass("active");
        $("#editTeamModal").off("hidden.bs.modal").on("hidden.bs.modal", function() {
            $("#teamsContainer").find(".team").find("button.active").removeClass("active");
        });
        openEditTeamModal($(this).parent().parent().data("number"));
    });

    // Bind edit member modal to the edit member button
    $(".team-member button").on("click", function() {
        $(this).addClass("active");
        $("#editMemberModal").off("hidden.bs.modal").on("hidden.bs.modal", function() {
            $("#teamsContainer").find(".team").find("button.active").removeClass("active");
        });
        openEditMemberModal($(this).parent().data("member-id"));
    });
}

function fetchAndLoadTeams(search="", sortGroups="", sortMembers="") {
    $.ajax({
        url: getTeamsUrl,
        type: "post",
        data: {
            "csrfmiddlewaretoken": csrfMiddlewareToken,
            "search": search,
            "sortGroups": sortGroups,
            "sortMembers": sortMembers
        },
        error: (xhr, textStatus, errorThrown) => { alert(xhr + " " + textStatus + " " + errorThrown); },
        success: (result) => {
            teamsLoading(false);
            loadTeams(result.groups, search, result.sortGroups);
        }
    });
}


function teamsLoading(show=true) {
    $("#teamsNotFound").hide()

    if (show) {
        $("#groupsContainer").hide();
        $("#teamsLoadingSpinner").show();
        return
    }

    $("#groupsContainer").show();
    $("#teamsLoadingSpinner").hide();
}

function openEditSectionModal(sectionId) {

    $("#editSectionNameError").hide();
    $("#editSectionModal").modal("show");

    $("#saveEditSectionModal").off("click").on("click", () => {

        if(!$("#editSectionName").val().match(/^[A-Za-z]+$/)) {
            $("#editSectionName").focus();
            $("#editSectionNameError").text("Invalid section character").show();
            return;
        }


        teamsLoading(true);
        const [search, sortGroups, sortMembers] = getFilters();

        const getGroupTask = sortGroups === "teams" ? "get-teams": "get-sections"
        const loadFunction = sortGroups === "teams" ? displayTeams : displaySections;

        $.ajax({
            url: pageUrl,
            type: "post",
            data: {
                "csrfmiddlewaretoken": csrfMiddlewareToken,
                "tasks": ["update-section", getGroupTask, "get-anglers"],
                "id": sectionId,
                "character": $("#editSectionName").val().toUpperCase(),
                "search": search,
            },
            error: (xhr, textStatus, errorThrown) => { alert(xhr + " " + textStatus + " " + errorThrown); },
            success: (result) => {
                
                if (Object.keys(result.form_errors).length > 0) {
                    for (const errorId in result.form_errors) {
                        $(errorId).text(result.form_errors[errorId]).show();
                    }
                    return;
                }

                alert(JSON.stringify(result));
                alert(sortGroups);
                loadFunction(result[sortGroups], result.anglers);

                $("#editSectionModal").modal("hide");
            }
        });

        teamsLoading(false);
    });
}

function openEditTeamModal(teamId) {

    $("#editTeamModal").modal("show");

    $("#saveEditTeamModal").off("click").on("click", () => {
        teamsLoading(true);

        const [search, sortGroups, sortMembers] = getFilters()

        $.ajax({
            url: updateTeamUrl,
            type: "post",
            data: {
                "csrfmiddlewaretoken": csrfMiddlewareToken,
                "tasks": ["update-team"],
                "id": teamId,
                "number": $("#editTeamNumber").val(),
                "search": search,
            },
            error: (xhr, textStatus, errorThrown) => { alert(xhr + " " + textStatus + " " + errorThrown); },
            success: (result) => {
                
                if (Object.keys(result.form_errors).length > 0) {
                    alert(JSON.stringify(result));
                    for (const errorId in result.form_errors) {
                        $(errorId).focus();
                        $(errorId).text(result.form_errors[errorId]).show();
                    }
                    return;
                }

                $("#editTeamModal").modal("hide");
            }
        });

        teamsLoading(false);
    });
}

function openEditMemberModal(memberId) {

    // var modalTitle = "Add Member";
    // var first = "";
    // var last = "";
    // var teamNumber = $(".team").map(function() { return $(this).data("number"); }).get();  // TODO: shorten this
    // var pegNumber = 0;
    // var firstPlaceholder = "Forename";
    // var lastPlaceholder = "Surname";   

    // // Member data
    // if (memberId !== -1) {
    //     const member = $(`.team-member[data-member-id='${memberId}']`);
    //     first = member.data("first");
    //     last = member.data("last");
    //     teamNumber = member.data("team-number");
    //     pegNumber = member.data("peg-number");
    //     firstPlaceholder = first;
    //     lastPlaceholder = last;
    //     modalTitle = "Edit: " + first + " " + last        
    // }

    // Load teams as options
    $("#editMemberTeam").html("");
    globalTeamsList.forEach((team) => {
        $("#editMemberTeam").append(`<option value='${team.id}'>Team ${team.number}</option>`);
    });


    $("#editMemberSection").html("");
    globalSectionsList.forEach((section) => {
        $("#editMemberSection").append(`<option value='${section.id}'>Section ${section.character}</option>`);
    });

    // // Load data to form
    // $("#editMemberName").text(modalTitle);
    // $("#editMemberFirstName").val(first);
    // $("#editMemberLastName").val(last);
    // $("#editMemberTeam").val(teamNumber);
    // $("#editMemberPeg").val(pegNumber);

    // $("#editMemberFirstName").attr("placeholder", firstPlaceholder);
    // $("#editMemberLastName").attr("placeholder", lastPlaceholder);

    $("#editMemberModal").modal("show");

    // Update the submit button
    $("#saveEditModal").off("click").on("click", () => {
        alert("you pressed save member");
    });
}


function saveEditMemberModal(memberId) {

    if (!$("#editMemberForm").valid()) {
        return;
    }

    // Grab the updated data
    const first = $("#editMemberFirstName").val();
    const last = $("#editMemberLastName").val();
    const teamNumber = $("#editMemberTeam").val();
    const pegNumber = $("#editMemberPeg").val();
    const search = $("#search").val();

    teamsLoading(true);

    $.ajax({
        url: updateMemberUrl,
        type: "post",
        data: {
            "csrfmiddlewaretoken": csrfMiddlewareToken,
            "memberId": memberId,
            "first": first,
            "last": last,
            "teamNumber": teamNumber,
            "pegNumber": pegNumber,
            "search": !isEmptyOrSpaces(search) ? search : null
        },
        error: (xhr, textStatus, errorThrown) => { alert(xhr + " " + textStatus + " " + errorThrown); },
        success: (result) => {
            teamsLoading(false);
            loadTeams(result.teams, search, result.sortGroups);
            $("#editMemberModal").modal("hide");
        }
    });
}










//      REWRITE BEYOND THIS POINT

$(document).ready(() => {


    // Bind new member/team buttons
    $("#addTeam").on("click", () => {
        openEditTeamModal(-1);
    });

    $("#addMember").on("click", () => {
        openEditMemberModal(-1);
    });

    $("#addSection").on("click", () => {
        openEditSectionModal(-1);
    });
});

function fetchAndLoadPageData() {

    teamsLoading(true);

    const [search, sortGroups, sortMembers] = getFilters();

    $.ajax({
        url: getPageDataUrl,
        type: "post",
        data: {
            "csrfmiddlewaretoken": csrfMiddlewareToken,
            "search": search,
            "sortGroups": sortGroups,
            "sortMembers": sortMembers
        },
        error: (xhr, textStatus, errorThrown) => {
            alert(xhr + " " + textStatus + " " + errorThrown);
        },
        success: (result) => {
            loadPageData(result.teams, result.sections, result.anglers, result.sortGroups);
        }
    });

    teamsLoading(false);
}

function loadPageData(teams, sections, anglers, displayGroups) {

    $("#groupsContainer").html("");

    globalTeamsList = teams;
    globalSectionsList = sections;
    globalAnglersList = anglers;

    if (displayGroups === "section") {
        // displaySections();
    }
    else if (displayGroups === "team") {
        displayTeams();
    }
    else {
        throw new Error(`invalid display groups '${displayGroups}'`);
    }

    activateTooltips();
}


function displaySections(sections, anglers) {

    sections.forEach((section) => {
        $("#groupsContainer").append(getGroupTemplate(section.id, "section", section.character));

        anglers.forEach((angler) => {
            if (angler.section_id != section.id) { return; }

            const team = findByKey(globalTeamsList, "id", angler.team_id).number;
            $("#groupsContainer").find(".anglers").last().append(getAnglerTemplate(angler, "Team", team));
        });
    });
}

function displayTeams() {

    globalTeamsList.forEach((team) => {
        $("#groupsContainer").append(getGroupTemplate(team.id, "team", team.number));

        globalAnglersList.forEach((angler) => {
            if (angler.team_id != team.id) { return; }

            const section = findByKey(globalSectionsList, "id", angler.section_id).character;
            $("#groupsContainer").find(".anglers").last().append(getAnglerTemplate(angler, "Section", section));
        });
    });
}

function getGroupTemplate(groupId, groupType, groupName) {
    return`
        <div class='col-12 col-md-6 col-xl-4 mb-4'>
            <div
                class='group px-4 py-3 bg-body-tertiary bg-gradient rounded h-100 fluid-hover-zoom shadow-sm md-shadow-on-hover'
                data-id='${groupId}'>
                <h3>
                    <span class='fs-4'>
                        <span class='fs-6'>${groupType.toUpperCase()}</span> 
                        ${groupName}
                    </span>
                    <button class='btn btn-sm btn-light float-end border-0 me-1'>
                        <i class='bi bi-gear fs-6'></i>
                    </button>
                </h3>
                <ul class='list-unstyled anglers mt-3'>
                </ul>
            </div>
        </div>
    `;
}

function getAnglerTemplate(angler, oppositeGroupType, oppositeGroupName) {
    const fullname = angler.first + " " + angler.last;
    return `
        <li class='mb-3 rounded w-100 fluid-hover-zoom'>
            <div 
                class='angler d-flex'
                data-first='${angler.first}'
                data-last='${angler.last}'
                data-member-id='${angler.id}'
                data-peg='${angler.peg}'
                data-team-id='${angler.team_id}'
                data-section-id='${angler.section_id}'>
                <div class='px-3 py-2 w-100'>
                    <div class='badge bg-secondary-subtle text-body fixed-badge' data-bs-title='Peg ${angler.peg}' data-bs-toggle='tooltip'>
                        ${angler.peg}
                    </div>
                    <div class='badge bg-secondary-subtle text-body fixed-badge' data-bs-title='${oppositeGroupType} ${oppositeGroupName}' data-bs-toggle='tooltip'>
                        ${oppositeGroupName}
                    </div>
                    <div class='d-inline-block ms-2 angler-fullname'>
                        ${fullname}
                    </div>
                </div>
                <button type='button' class='ms-auto btn btn-light border-0 fs-6 pencil-btn align-self-center me-1 force-contents-center'>
                    <i class='bi bi-pencil'></i>
                </button>
            </div>
        </li>
    `;
}