{% load static %}

<style>
/* Ensure map container and its elements stay below other UI elements */
.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
    z-index: 1 !important;
}
.leaflet-control {
    z-index: 2 !important;
}
</style>

<div class="p-4 bg-white border rounded-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50">
    <h3 class="mb-4 text-lg font-semibold text-gray-900 dark:text-gray-300">Location</h3>
    
    <div class="location-widget" id="locationWidget-{{ submission.id }}">
        {# Search Form #}
        <div class="relative mb-4">
            <label class="block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300">
                Search Location
            </label>
            <input type="text" 
                   id="locationSearch-{{ submission.id }}"
                   class="relative w-full px-4 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600 form-input"
                   placeholder="Search for a location..."
                   autocomplete="off"
                   style="z-index: 10;">
            <div id="searchResults-{{ submission.id }}"
                 style="position: absolute; top: 100%; left: 0; right: 0; z-index: 1000;"
                 class="hidden w-full mt-1 overflow-auto bg-white border rounded-md shadow-lg max-h-60 dark:bg-gray-700 dark:border-gray-600">
            </div>
        </div>

        {# Map Container #}
        <div class="relative mb-4" style="z-index: 1;">
            <div id="locationMap-{{ submission.id }}" 
                 class="h-[300px] w-full rounded-lg border border-gray-300 dark:border-gray-600"></div>
        </div>

        {# Location Form Fields #}
        <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div>
                <label class="block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300">
                    Street Address
                </label>
                <input type="text" 
                       name="street_address" 
                       id="streetAddress-{{ submission.id }}"
                       class="w-full px-4 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600 form-input"
                       value="{{ submission.changes.street_address }}">
            </div>
            <div>
                <label class="block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300">
                    City
                </label>
                <input type="text" 
                       name="city" 
                       id="city-{{ submission.id }}"
                       class="w-full px-4 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600 form-input"
                       value="{{ submission.changes.city }}">
            </div>
            <div>
                <label class="block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300">
                    State/Region
                </label>
                <input type="text" 
                       name="state" 
                       id="state-{{ submission.id }}"
                       class="w-full px-4 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600 form-input"
                       value="{{ submission.changes.state }}">
            </div>
            <div>
                <label class="block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300">
                    Country
                </label>
                <input type="text" 
                       name="country" 
                       id="country-{{ submission.id }}"
                       class="w-full px-4 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600 form-input"
                       value="{{ submission.changes.country }}">
            </div>
            <div>
                <label class="block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300">
                    Postal Code
                </label>
                <input type="text" 
                       name="postal_code" 
                       id="postalCode-{{ submission.id }}"
                       class="w-full px-4 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600 form-input"
                       value="{{ submission.changes.postal_code }}">
            </div>
        </div>

        {# Hidden Coordinate Fields #}
        <div class="hidden">
            <input type="hidden" name="latitude" id="latitude-{{ submission.id }}" value="{{ submission.changes.latitude }}">
            <input type="hidden" name="longitude" id="longitude-{{ submission.id }}" value="{{ submission.changes.longitude }}">
        </div>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    let maps = {};
    let markers = {};
    const searchInput = document.getElementById('locationSearch-{{ submission.id }}');
    const searchResults = document.getElementById('searchResults-{{ submission.id }}');
    let searchTimeout;

    // Initialize form fields with existing values
    const fields = {
        city: '{{ submission.changes.city|default:"" }}',
        state: '{{ submission.changes.state|default:"" }}',
        country: '{{ submission.changes.country|default:"" }}',
        postal_code: '{{ submission.changes.postal_code|default:"" }}',
        street_address: '{{ submission.changes.street_address|default:"" }}',
        latitude: '{{ submission.changes.latitude|default:"" }}',
        longitude: '{{ submission.changes.longitude|default:"" }}'
    };

    Object.entries(fields).forEach(([field, value]) => {
        const element = document.getElementById(`${field}-{{ submission.id }}`);
        if (element) {
            element.value = value;
        }
    });

    // Set initial search input value if location exists
    if (fields.street_address || fields.city) {
        const parts = [
            fields.street_address,
            fields.city,
            fields.state,
            fields.country
        ].filter(Boolean);
        searchInput.value = parts.join(', ');
    }

    function normalizeCoordinate(value, maxDigits, decimalPlaces) {
        if (!value) return null;
        try {
            const rounded = Number(value).toFixed(decimalPlaces);
            const strValue = rounded.replace('.', '').replace('-', '');
            const strippedValue = strValue.replace(/0+$/, '');
            
            if (strippedValue.length > maxDigits) {
                return Number(Number(value).toFixed(decimalPlaces - 1));
            }
            
            return rounded;
        } catch (error) {
            console.error('Coordinate normalization failed:', error);
            return null;
        }
    }

    function validateCoordinates(lat, lng) {
        const normalizedLat = normalizeCoordinate(lat, 9, 6);
        const normalizedLng = normalizeCoordinate(lng, 10, 6);

        if (normalizedLat === null || normalizedLng === null) {
            throw new Error('Invalid coordinate format');
        }

        const parsedLat = parseFloat(normalizedLat);
        const parsedLng = parseFloat(normalizedLng);

        if (parsedLat < -90 || parsedLat > 90) {
            throw new Error('Latitude must be between -90 and 90 degrees.');
        }
        if (parsedLng < -180 || parsedLng > 180) {
            throw new Error('Longitude must be between -180 and 180 degrees.');
        }

        return { lat: normalizedLat, lng: normalizedLng };
    }

    function initMap() {
        const submissionId = '{{ submission.id }}';
        const mapId = `locationMap-${submissionId}`;
        const mapContainer = document.getElementById(mapId);
        
        if (!mapContainer) {
            console.error(`Map container ${mapId} not found`);
            return;
        }

        // If map already exists, remove it
        if (maps[submissionId]) {
            maps[submissionId].remove();
            delete maps[submissionId];
            delete markers[submissionId];
        }

        // Create new map
        maps[submissionId] = L.map(mapId);
        
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(maps[submissionId]);

        // Initialize with existing coordinates if available
        const initialLat = fields.latitude;
        const initialLng = fields.longitude;
        
        if (initialLat && initialLng) {
            try {
                const normalized = validateCoordinates(initialLat, initialLng);
                maps[submissionId].setView([normalized.lat, normalized.lng], 13);
                addMarker(normalized.lat, normalized.lng);
            } catch (error) {
                console.error('Invalid initial coordinates:', error);
                maps[submissionId].setView([0, 0], 2);
            }
        } else {
            maps[submissionId].setView([0, 0], 2);
        }

        // Handle map clicks
        maps[submissionId].on('click', async function(e) {
            try {
                const normalized = validateCoordinates(e.latlng.lat, e.latlng.lng);
                const response = await fetch(`/parks/search/reverse-geocode/?lat=${normalized.lat}&lon=${normalized.lng}`);
                if (!response.ok) {
                    throw new Error('Geocoding request failed');
                }
                const data = await response.json();
                if (data.error) {
                    throw new Error(data.error);
                }
                updateLocation(normalized.lat, normalized.lng, data);
            } catch (error) {
                console.error('Location update failed:', error);
                alert(error.message || 'Failed to update location. Please try again.');
            }
        });
    }

    function addMarker(lat, lng) {
        const submissionId = '{{ submission.id }}';
        if (markers[submissionId]) {
            markers[submissionId].remove();
        }
        markers[submissionId] = L.marker([lat, lng]).addTo(maps[submissionId]);
        maps[submissionId].setView([lat, lng], 13);
    }

    function updateLocation(lat, lng, data) {
        try {
            const normalized = validateCoordinates(lat, lng);
            const submissionId = '{{ submission.id }}';
            
            // Update coordinates
            document.getElementById(`latitude-${submissionId}`).value = normalized.lat;
            document.getElementById(`longitude-${submissionId}`).value = normalized.lng;
            
            // Update marker
            addMarker(normalized.lat, normalized.lng);
            
            // Update form fields with English names where available
            const address = data.address || {};
            document.getElementById(`streetAddress-${submissionId}`).value = 
                `${address.house_number || ''} ${address.road || address.street || ''}`.trim() || '';
            document.getElementById(`city-${submissionId}`).value = 
                address.city || address.town || address.village || '';
            document.getElementById(`state-${submissionId}`).value = 
                address.state || address.region || '';
            document.getElementById(`country-${submissionId}`).value = address.country || '';
            document.getElementById(`postalCode-${submissionId}`).value = address.postcode || '';

            // Update search input
            const locationString-3 = [
                document.getElementById(`streetAddress-${submissionId}`).value,
                document.getElementById(`city-${submissionId}`).value,
                document.getElementById(`state-${submissionId}`).value,
                document.getElementById(`country-${submissionId}`).value
            ].filter(Boolean).join(', ');
            searchInput.value = locationString;
        } catch (error) {
            console.error('Location update failed:', error);
            alert(error.message || 'Failed to update location. Please try again.');
        }
    }

    function selectLocation(result) {
        if (!result) return;
        
        try {
            const lat = parseFloat(result.lat);
            const lon = parseFloat(result.lon);
            
            if (isNaN(lat) || isNaN(lon)) {
                throw new Error('Invalid coordinates in search result');
            }
            
            const normalized = validateCoordinates(lat, lon);
            
            // Create a normalized address object
            const address = {
                name: result.display_name || result.name || '',
                address: {
                    house_number: result.address ? result.address.house_number : '',
                    road: result.address ? (result.address.road || result.address.street) : '',
                    city: result.address ? (result.address.city || result.address.town || result.address.village) : '',
                    state: result.address ? (result.address.state || result.address.region) : '',
                    country: result.address ? result.address.country : '',
                    postcode: result.address ? result.address.postcode : ''
                }
            };
            
            updateLocation(normalized.lat, normalized.lng, address);
            searchResults.classList.add('hidden');
            searchInput.value = address.name;
        } catch (error) {
            console.error('Location selection failed:', error);
            alert(error.message || 'Failed to select location. Please try again.');
        }
    }

    // Handle location search
    searchInput.addEventListener('input', function() {
        clearTimeout(searchTimeout);
        const query = this.value.trim();
        
        if (!query) {
            searchResults.classList.add('hidden');
            return;
        }

        searchTimeout = setTimeout(async function() {
            try {
                const response = await fetch(`/parks/search/location/?q=${encodeURIComponent(query)}`);
                if (!response.ok) {
                    throw new Error('Search request failed');
                }
                const data = await response.json();
                
                if (data.results && data.results.length > 0) {
                    const resultsHtml = data.results.map((result, index) => `
                        <div class="p-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600"
                             data-result-index="${index}">
                            <div class="font-medium text-gray-900 dark:text-white">${result.display_name || result.name || ''}</div>
                            <div class="text-sm text-gray-500 dark:text-gray-400">
                                ${(result.address && result.address.city) ? result.address.city + ', ' : ''}${(result.address && result.address.country) || ''}
                            </div>
                        </div>
                    `).join('');
                    
                    searchResults.innerHTML = resultsHtml;
                    searchResults.classList.remove('hidden');
                    
                    // Store results data
                    searchResults.dataset.results = JSON.stringify(data.results);
                    
                    // Add click handlers
                    searchResults.querySelectorAll('[data-result-index]').forEach(el => {
                        el.addEventListener('click', function() {
                            const results = JSON.parse(searchResults.dataset.results);
                            const result = results[this.dataset.resultIndex];
                            selectLocation(result);
                        });
                    });
                } else {
                    searchResults.innerHTML = '<div class="p-2 text-gray-500 dark:text-gray-400">No results found</div>';
                    searchResults.classList.remove('hidden');
                }
            } catch (error) {
                console.error('Search failed:', error);
                searchResults.innerHTML = '<div class="p-2 text-red-500 dark:text-red-400">Search failed. Please try again.</div>';
                searchResults.classList.remove('hidden');
            }
        }, 300);
    });

    // Hide search results when clicking outside
    document.addEventListener('click', function(e) {
        if (!searchResults.contains(e.target) && e.target !== searchInput) {
            searchResults.classList.add('hidden');
        }
    });

    // Initialize map when the element becomes visible
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
                const mapContainer = document.getElementById(`locationMap-{{ submission.id }}`);
                if (mapContainer && window.getComputedStyle(mapContainer).display !== 'none') {
                    initMap();
                    observer.disconnect();
                }
            }
        });
    });

    const mapContainer = document.getElementById(`locationMap-{{ submission.id }}`);
    if (mapContainer) {
        observer.observe(mapContainer.parentElement.parentElement, { attributes: true });
        
        // Also initialize immediately if the container is already visible
        if (window.getComputedStyle(mapContainer).display !== 'none') {
            initMap();
        }
    }
});
</script>
