var marker = null;
    map = null;
    originalMapCoords = [51.509865, -0.118092];
    isGeocodingInProgress = false;
    scriptData = document.currentScript.dataset;

const formControls = [
    // Details Tab
    {
        id: "venueName",
        validation: function (element) {
            const value = element.val();                                 // FIELD IS VALID IF:
            return (!element.attr("required") || value.trim() !== "");  //  - element is not required OR not empty 
        },
        errorMessage: function (element) {
            const minlength = element.attr("minlength");
            return `Enter a venue name longer than ${minlength} characters`;
        }
    },
    {
        id: "venueType",
        validation: function (element) {
            const value = element.val();                                 // FIELD IS VALID IF:
            return (!element.attr("required") || value !== null);  //  - element is not required OR not empty 
        },
        errorMessage: function (element) {
            return "Please selected a type of venue";
        }
    },
    // Address Tab
    {
        id: "venueStreetAddress",
        validation: function (element) {
            const value = element.val();
            return (!element.attr("required") || value.trim() !== "");
        },
        errorMessage: function (element) {
            return "Enter the street address of the venue";
        }
    },
    {
        id: "venueCity",
        validation: function (element) {
            const value = element.val();
            return (!element.attr("required") || value.trim() !== "");
        },
        errorMessage: function (element) {
            return "Enter the town or city of the venue";
        }
    },
    {
        id: "venueProvence",
        validation: function (element) {
            const value = element.val();
            return (!element.attr("required") || value.trim() !== "");
        },
        errorMessage: function (element) {
            return "Enter the provence of the venue";
        }
    },
    {
        id: "venuePostCode",
        validation: function (element) {
            const value = element.val();
            return (!element.attr("required") || value.trim() !== "");
        },
        errorMessage: function (element) {
            return "Enter the postal code of the venue";
        }
    },
    {
        id: "venueLatitude",
        validation: function (element) {
            const value = element.val();
            return (!element.attr("required") || value.trim() !== "");
        },
        errorMessage: function (element) {
            return "Enter the latitude of the venue";
        }
    },
    {
        id: "venueLongitude",
        validation: function (element) {
            const value = element.val();
            return (!element.attr("required") || value.trim() !== "");
        },
        errorMessage: function (element) {
            return "Enter the longitude of the venue";
        }
    },

];

$("#newVenueAddressTabBtn").on("shown.bs.tab", function() {
    
    if (!map) {
        var tileLayer = L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: false,
        })

        map = L.map("locationMap", {
            center: originalMapCoords,
            zoom:8,
            layers: [tileLayer]
        });

        const UKSouthWest = L.latLng(49.823809, -8.649357);
        const UKNorthEast = L.latLng(60.905124, 2.637773);
        const UKBounds = L.latLngBounds(UKSouthWest, UKNorthEast);

        map.setMaxBounds(UKBounds);
    }

    venueCoords = {
        lat: $("#venueLatitude").val(),
        lng: $("#venueLongitude").val()
    };
    if (venueCoords.lat && venueCoords.lng) {
        map.setView(new L.LatLng(venueCoords.lat, venueCoords.lng), 15);
        marker = L.marker(venueCoords).addTo(map);
    }

    map.on('click', function (e) {
        if (isGeocodingInProgress) {
            return;
        }

        toggleLoadingMap(true);
        var coordinates = e.latlng;
        
        // Create a point feature from the clicked coordinates
        var clickedPoint = turf.point([coordinates.lng, coordinates.lat]);

        // Define the UK boundary polygon coordinates (simplified for illustration)
        var ukBoundary = turf.polygon([
            [
                [-8.647, 59.688], // Northwest corner
                [-8.647, 49.784], // Southwest corner
                [1.768, 49.784],  // Southeast corner
                [1.768, 59.688],  // Northeast corner
                [-8.647, 59.688]  // Close the polygon
            ]
        ]);

        if (marker) {
            map.removeLayer(marker);
        }

        marker = L.marker(coordinates).addTo(map);
        var isInsideUK = turf.booleanPointInPolygon(clickedPoint, ukBoundary);

        if (!isInsideUK) {
            alert("Please select a point within the UK");
            map.removeLayer(marker);
            toggleLoadingMap(false);
            return false;
        }

        fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${coordinates.lat}&lon=${coordinates.lng}`)
            .then(response => response.json())
            .then(data => {
                data.address;  // check promise first

                toggleLoadingMap(false);
                $("#venueStreetAddress").val(data.address.road || '');
                $("#venueCity").val(data.address.village || data.address.town || data.address.city);
                $("#venueProvence").val(data.address.county || data.address.state_district);
                $("#venuePostCode").val(data.address.postcode || '');
                // $("#venueCountry").val(data.address.country || '');
                $("#venueLatitude").val(coordinates.lat);
                $("#venueLongitude").val(coordinates.lng);
            });
        });

    setTimeout(function() {map.invalidateSize(false)}, 200)
});

function toggleLoadingMap(isLoading) {
    isGeocodingInProgress = isLoading;
    $("#saveVenue").prop("disabled", isLoading);
    $("#venueStreetAddress").prop("disabled", isLoading)
    $("#venueCity").prop("disabled", isLoading)
    $("#venueProvence").prop("disabled", isLoading)
    $("#venuePostCode").prop("disabled", isLoading)
    // $("#venueCountry").prop("disabled", isLoading)
    if (isLoading) {
        $("#locationMapOverlay").show();
    }
    else {
        $("#locationMapOverlay").hide();
    }
}

$("#venueModal").on("hidden.bs.modal", function() {
    // Reset the map if we are done
    if (map) {
        map.setView(originalMapCoords, 8);

        if (marker) {
            map.removeLayer(marker);
        }
    }
});

function openVenueModal(venue_id) {
    $("#venueModal").data("venue-id", venue_id);
    const detailsTab = new bootstrap.Tab("#newVenueDetailsTabBtn");
    detailsTab.show();  // back to the first tab

    $("#venueForm .form-control, #venueForm .form-select").removeClass("is-valid is-invalid");
    $("#venueForm .invalid-feedback").text("");

    if (venue_id == -1) {
        $("#venueModal .edit").hide();
        $("#venueModal .create").show();

        $("#venueName").val("");
        $("#venueType").val("").change();
        $("#venueDescription").val("");
        $("#venueExtraNotes").val("");

        $("#venueStreetAddress").val("");
        $("#venueCity").val("");
        $("#venueProvence").val("");
        $("#venuePostCode").val("");
        // $("#venueCountry").val("");
        $("#venueLatitude").val("");
        $("#venueLongitude").val("");

        $("#venuePhone").val("");
        $("#venueEmail").val("");
        $("#venueWebsite").val("");

        $("#venueTwitter").val("");
        $("#venueFacebook").val("");
        $("#venueInstagram").val("");
    }
    else {
        $("#venueModal .edit").show();
        $("#venueModal .create").hide();

        $.ajax({
            url: `/venues/api/${venue_id}`,
            method: 'get',
            dataType: 'json',
            success: function(response) {
                const venue = response.data;

                $("#venueName").val(venue.name);
                $("#venueType").val(venue.venue_type).change();
                $("#venueDescription").val(venue.description);
                $("#venueExtraNotes").val(venue.extra_notes);

                $("#venueStreetAddress").val(venue.street_address);
                $("#venueCity").val(venue.city);
                $("#venueProvence").val(venue.provence);
                $("#venuePostCode").val(venue.postal_code);
                // $("#venueCountry").val(venue.country);
                $("#venueLatitude").val(venue.latitude);
                $("#venueLongitude").val(venue.longitude);

                $("#venuePhone").val(venue.phone_number);
                $("#venueEmail").val(venue.email_address);
                $("#venueWebsite").val(venue.website_url);

                $("#venueTwitter").val(venue.twitter_url);
                $("#venueFacebook").val(venue.facebook_url);
                $("#venueInstagram").val(venue.instagram_url);
            },
            error: function(error) {
                alert("error: " + JSON.stringify(error));
            }
        });
    }

    new bootstrap.Modal("#venueModal").show();
}

$("#venueForm").on("submit", function(event) {
    event.preventDefault();
    const valid = validateVenue();
    if (valid) saveVenue();
});

function validateVenue() {
    
    // Reset the validation indicators and messages
    $("#venueForm .form-control, #venueForm .form-select").removeClass("is-valid is-invalid");
    $("#venueForm .invalid-feedback").text("");

    var valid = true;

    formControls.forEach(function(control) {
        var element = $("#" + control.id);
        if (!control.validation(element)) {
            element.addClass("is-invalid");
            element.siblings(".invalid-feedback").text(control.errorMessage(element));
            valid = false;
        }
        else {
            element.addClass("is-valid");
        }
    });

    return valid;
}

function saveVenue() {
    var data = {
        name: $("#venueName").val(),
        description: $("#venueDescription").val(),
        extra_notes: "* placeholder *",
        venue_type: $("#venueType").val(),

        street_address: $("#venueStreetAddress").val(),
        city: $("#venueCity").val(),
        provence: $("#venueProvence").val(),
        postal_code: $("#venuePostCode").val(),
        country: $("#venueCountry").val(),
        longitude: $("#venueLongitude").val(),
        latitude: $("#venueLatitude").val(),

        phone_number: $("#venuePhone").val(),
        email_address: $("#venueEmail").val(),
        website_url: $("#venueWebsite").val(),

        twitter_url: $("#venueTwitter").val(),
        facebook_url: $("#venueFacebook").val(),
        instagram_url: $("#venueInstagram").val(),

        csrfmiddlewaretoken: scriptData.csrfmiddlewaretoken,
        active: 1
    }

    const venue_id = $("#venueModal").data("venue-id");
    data.id = venue_id > -1 ? venue_id : null;

    $.ajax({
        url: `/venues/api/create`,
        method: 'post',
        dataType: 'json',
        data: data,
        success: function(response) {
            window.location.reload();
        },
        error: function(error) {
            alert("error: " + JSON.stringify(error));
        }
    });
}

$("#newVenueTabLeft").on("click", function() {

    const currentTab = $("#newVenueTabBtns .nav-link.active").parent();
    const previousTabParent = currentTab.prev();
    const previousTab = previousTabParent.find(".nav-link");
    previousTab.click();

    if (previousTabParent.is(":first-child")) {
        $("#newVenueTabLeft").prop("disabled", true);
        $("#newVenueTabRight").prop("disabled", false);
    }
    else {
        $("#newVenueTabRight").prop("disabled", false);
        $("#saveVenue").hide();
    }

});

$("#newVenueTabRight").on("click", function() {

    const currentTab = $("#newVenueTabBtns .nav-link.active").parent();
    const nextTabParent = currentTab.next();
    const nextTab = nextTabParent.find(".nav-link");
    nextTab.click();

    if (nextTabParent.is(":last-child")) {
        $("#newVenueTabRight").prop("disabled", true);
        $("#saveVenue").show();
        $("#newVenueTabLeft").prop("disabled", false);
    }
    else {
        $("#newVenueTabLeft").prop("disabled", false);
    }

});