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

    toggleLoading(true);

    // Search Bar Functionality

    searchTimeout = null;

    $("#search").on("input", () => {
        clearTimeout(searchTimeout);
        toggleLoading(true);

        searchTimeout = setTimeout(() => {
            fetchAndLoadGroups();
        }, 500)
    });

    $("#searchButton").on("click", () => {
        fetchAndLoadGroups();
    });

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

        fetchAndLoadGroups();
    });

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

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

    // Modals

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

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

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

    fetchAndLoadGroups();

});

function fetchAndLoadGroups() {
    toggleLoading(true);

    const showGroups = localStorage.getItem("showGroups");
    const sortAnglers = localStorage.getItem("sortAnglers");
    const task = showGroups === "teams" ? "get-teams" : "get-sections";
    const search = $("#search").val()
    $.ajax({
        type: "POST",
        url: pageUrl,
        data: {
            csrfmiddlewaretoken: csrfMiddlewareToken,
            tasks: [task, "get-anglers"],
            sortAnglers: sortAnglers,
            search: isEmptyOrSpaces(search) ? "" : search,
        },
        error: (error) => {
            console.error(error);
        },
        success: (data) => {
            loadGroups(data);
        }
    });

    toggleLoading(false);
}

function groupTemplate(group, groupType, oppositeGroupType) {
    groupValue = groupType === "teams" ? group.number : group.character
    const nonPluralGroupType = groupType.slice(0, -1);
    const editFunction = groupType === "teams"? "addTeam" : "addSection";

    return `
        <div class='col-12 col-md-6 col-xl-4 mb-4'>
            <div
                class='${nonPluralGroupType.toLowerCase()} px-4 py-3 bg-body-tertiary bg-gradient rounded h-100 fluid-hover-zoom shadow-sm md-shadow-on-hover'
                data-id='${group.id}' data-value='${groupValue}'>
                <h3>
                    <span class='fs-4'>
                        <span class='fs-6'>${nonPluralGroupType.toUpperCase()}</span> 
                        ${groupValue}
                    </span>
                    <button onclick='${editFunction}(${group.id})' 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 anglerTemplate(angler, oppositeGroupType) {
    const fullname = angler.first_name + " " + angler.last_name;
    const oppositeGroupValue = oppositeGroupType === "teams"? angler.team_number : angler.section_character;

    var oppositeGroup = oppositeGroupType.slice(0, -1);
    oppositeGroup = oppositeGroup.charAt(0).toUpperCase() + oppositeGroup.slice(1);

    return `
        <li class='mb-2 rounded w-100 fluid-hover-zoom'>
            <div 
                class='angler d-flex'
                data-first='${angler.first_name}'
                data-last='${angler.last_name}'
                data-id='${angler.id}'
                data-peg-number='${angler.peg_number}'
                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_number}' data-bs-toggle='tooltip'>
                        ${angler.peg_number}
                    </div>
                    <div class='badge bg-secondary-subtle text-body fixed-badge' data-bs-title='${oppositeGroup} ${oppositeGroupValue}' data-bs-toggle='tooltip'>
                        ${oppositeGroupValue}
                    </div>
                    <div class='d-inline-block ms-2 angler-fullname'>
                        ${fullname}
                    </div>
                </div>
                <button type='button' onclick="addAngler(${angler.id})" 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>
    `
}

function loadGroups(data) {
    const showGroups = localStorage.getItem("showGroups");
    const groupType = showGroups === "teams" ? "teams" : "sections";
    const oppositeGroupType = showGroups === "teams" ? "sections" : "teams";
    const groups = data[groupType];

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

    if (!groups.length) {
        $("#notFound").show();
        return;
    }

    groups.forEach((group) => {
        $("#groups").append(groupTemplate(group, groupType, oppositeGroupType));
        data.anglers.forEach((angler) => {
            if ((groupType == "teams" && angler.team_id === group.id) || (groupType == "sections" && angler.section_id === group.id)) {
                $("#groups").find(".anglers").last().append(
                    anglerTemplate(angler, oppositeGroupType)
                );
            }
        });
    });

    activateTooltips();

    if (!isEmptyOrSpaces($("#search").val())) {
        $("#groups").find('.angler-fullname').each(function() {
            var regex = new RegExp($("#search").val(), 'gi');
            $(this).html($(this).text().replace(regex, '<span class="text-company fw-bolder border-2 border-bottom border-company">$&</span>'));
        });
    }
}

/**
 * Shows a loading icon, hides groups and error alerts.
 * 
 * @param {Boolean} loading - Wether or not to show the loading icon 
 */
function toggleLoading(loading) {
    if (loading) {
        $("#groups").hide();
        $("#notFound").hide();
        $("#loadingSpinner").show();
    }
    else {
        $("#groups").show();
        $("#loadingSpinner").hide();
    }
}

/**
 * Open the modal for adding/editing an angler
 * 
 * @param {Number} anglerId - ID of the angler, if -1 will create a new angler 
 */
function addAngler(anglerId) {

    // Reset the form values
    $("#anglerTitle").text("Add New Angler");
    $("#anglerForename").val("");
    $("#anglerSurname").val("");
    $("#anglerTeam").empty().trigger("change");
    $("#anglerSection").empty().trigger("change");
    $("#anglerPeg").val(1);
    $("#anglerForm .error").text("").hide();
    $("#anglerDelete").hide();

    function validateSection() {
        const sectionId = $("#anglerSection").val();

        var valid = true;
    
        // Ensure that no teammates are in this section
        const teamId = $("#anglerTeam").val();
        $(`.team[data-id='${teamId}'] .angler`).each(function() {
            if ($(this).data("section-id") == sectionId && $(this).data("id") != anglerId) {
                valid = false;
                return false;
            }
            else {
                $("#anglerSectionError").text("").hide();
            }
        });

        return valid;
    }

    $("#anglerSection").change(() => {validateSection()});

    $.ajax({
        type: "POST",
        url: pageUrl,
        data: {
            csrfmiddlewaretoken: csrfMiddlewareToken,
            tasks: ["get-teams", "get-sections"]
        },
        error: (error) => {
            console.error(error);
        },
        success: (data) => {
            data.teams.forEach((team) => {
                $("#anglerTeam").append(`<option value='${team.id}'>Team ${team.number}</option>`);
            });
            data.sections.forEach((section) => {
                $("#anglerSection").append(`<option value='${section.id}'>Section ${section.character}</option>`);
            });

            if (anglerId !== -1) {
                const angler = $(`.angler[data-id='${anglerId}']`)
                const forename = angler.data("first");
                const surname = angler.data("last");
                const peg = angler.data("peg-number");
                const teamId = angler.data("team-id");
                const sectionId = angler.data("section-id");
        
                $("#anglerTitle").text(`Edit ${forename} ${surname}`);
                $("#anglerForename").val(forename);
                $("#anglerSurname").val(surname);
                $("#anglerTeam").val(teamId).trigger("change");
                $("#anglerSection").val(sectionId).trigger("change");
                $("#anglerPeg").val(peg);
                $("#anglerDelete").show();
            }
        }
    });

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

    $("#anglerForm").off("submit").on("submit", (e) => {
        e.preventDefault();

        $("#anglerForm .error").text("").hide();

        const forename = $("#anglerForename").val();
        const surname = $("#anglerSurname").val();
        const teamId = $("#anglerTeam").val();
        const sectionId = $("#anglerSection").val();
        const peg = $("#anglerPeg").val();
        const validSection = validateSection();
1
        var formErrors = !(forename && surname && teamId && sectionId && peg && validSection);

        // This form validation is not very scalable
        if (!forename) {
            $("#anglerForenameError").text("Please enter a forename").show();
        }
        if (!surname) {
            $("#anglerSurnameError").text("Please enter a surname").show();
        }
        if (!teamId) {
            $("#anglerTeamError").text("Please select a team").show();
        }
        if (!sectionId) {
            $("#anglerSectionError").text("Please select a section").show();
        }
        if (!peg) {
            $("#anglerPegError").text("Please enter a peg number").show();
        }
        if (!validSection) {
            $("#anglerSectionError").text("Anglers cannot share a section with a teammate").show();
        }
        if (formErrors) {
            return;
        }

        $.ajax({
            type: "POST",
            url: pageUrl,
            data: {
                csrfmiddlewaretoken: csrfMiddlewareToken,
                tasks: ["update-angler"],
                angler_id: anglerId,
                forename: forename,
                surname: surname,
                team_id: teamId,
                section_id: sectionId,
                peg_number: peg
            },
            error: (error) => {
                console.error(error);
            },
            success: (data) => {
                if (isEmpty(data.form_errors)) {
                    fetchAndLoadGroups();
                    $("#anglerModal").modal("hide");
                    return;
                }
                
                for(var inputId in data.form_errors) {
                    var errorMessage = data.form_errors[inputId];
                    $(`${inputId}Error`).text(errorMessage).show();
                }
            }
        });
    });

    $("#anglerDelete").off("click").on("click", () => {
        $.ajax({
            type: "POST",
            url: pageUrl,
            data: {
                csrfmiddlewaretoken: csrfMiddlewareToken,
                tasks: ["delete-angler"],   
                angler_id: anglerId
            },
            error: (error) => {
                console.error(error);
            },
            success: (data) => {
                fetchAndLoadGroups();
                $("#anglerModal").modal("hide");
                alert("Angler Deleted");
            }
        });
    });

    $("#anglerPegNext").off("click").on("click", () => {
        $.ajax({
            type: "POST",
            url: pageUrl,
            data: {
                csrfmiddlewaretoken: csrfMiddlewareToken,
                tasks: ["get-nextPegNumber"]
            },
            error: (error) => {
                console.error(error);
            },
            success: (data) => {
                $("#anglerPeg").val(data.nextPegNumber);
            }
        });
    });
}

/**
 * Open the modal for adding/editing a team
 * 
 * @param {Number} teamId - ID of the team, if -1 will create a new team
 */
function addTeam(teamId) {

    // Reset the form values
    $("#teamNumberError").text("").hide();

    if (teamId !== -1) {
        const team = $(`.team[data-id='${teamId}']`)
        const number = team.data("value");

        $("#teamTitle").text(`Edit Team #${number}`);
        $("#teamNumber").val(number);
        $("#teamDelete").show();
    }
    else {
        $("#teamTitle").text("Add New Team");
        $("#teamNumber").val(1);
        $("#teamDelete").hide();
    }

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

    $("#teamForm").off("submit").on("submit", (e) => {
        e.preventDefault();

        const number = $("#teamNumber").val();
        if (!number) {
            $("#teamNumberError").text("Please enter a team number").show();
            return;
        }

        $.ajax({
            type: "POST",
            url: pageUrl,
            data: {
                csrfmiddlewaretoken: csrfMiddlewareToken,
                tasks: ["update-team"],
                id: teamId,
                number: number
            },
            error: (error) => {
                console.error(error);
            },
            success: (data) => {
                if (isEmpty(data.form_errors)) {
                    fetchAndLoadGroups();
                    $("#teamModal").modal("hide");
                    return;
                }
                for(var inputId in data.form_errors) {
                    var errorMessage = data.form_errors[inputId];
                    $(`${inputId}Error`).text(errorMessage).show();
                }
            }
        });
    });

    $("#teamDelete").off("click").on("click", () => {
        $.ajax({
            type: "POST",
            url: pageUrl,
            data: {
                csrfmiddlewaretoken: csrfMiddlewareToken,
                tasks: ["delete-team"],   
                team_id: teamId
            },
            error: (error) => {
                console.error(error);
            },
            success: (data) => {
                fetchAndLoadGroups();
                $("#teamModal").modal("hide");
            }
        });
    });

    $("#teamNumberNext").off("click").on("click", () => {
        $.ajax({
            type: "POST",
            url: pageUrl,
            data: {
                csrfmiddlewaretoken: csrfMiddlewareToken,
                tasks: ["get-nextTeamNumber"]
            },
            error: (error) => {
                console.error(error);
            },
            success: (data) => {
                $("#teamNumber").val(data.nextTeamNumber);
            }
        });
    });
}

/**
 * Open the modal for adding/editing a section
 * 
 * @param {Number} sectionId - ID of the section, if -1 will create a new section
 */
function addSection(sectionId) {
    $("#sectionModal").modal("show");
}
