{% 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="location-widget" id="locationWidget">
    {# Search Form #}
    <div class="relative mb-4">
        <label class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
            Search Location
        </label>
        <input type="text" 
               id="locationSearch"
               class="relative w-full px-4 py-2 border border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
               placeholder="Search for a location..."
               autocomplete="off"
               style="z-index: 10;">
        <div id="searchResults"
             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" class="h-[300px] w-full rounded-lg border border-gray-300 dark:border-gray-600"></div>
    </div>

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

    {# Hidden Coordinate Fields #}
    <div class="hidden">
        <input type="hidden" name="latitude" id="latitude" value="{{ form.latitude.value|default:'' }}">
        <input type="hidden" name="longitude" id="longitude" value="{{ form.longitude.value|default:'' }}">
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    let map = null;
    let marker = null;
    const searchInput = document.getElementById('locationSearch');
    const searchResults = document.getElementById('searchResults');
    let searchTimeout;

    function normalizeCoordinate(value, maxDigits, decimalPlaces) {
        try {
            // Convert to string-3 with exact decimal places
            const rounded = Number(value).toFixed(decimalPlaces);
            
            // Convert to string-3 without decimal point for digit counting
            const strValue = rounded.replace('.', '').replace('-', '');
            // Remove trailing zeros
            const strippedValue = strValue.replace(/0+$/, '');
            
            // If total digits exceed maxDigits, round further
            if (strippedValue.length > maxDigits) {
                return Number(Number(value).toFixed(decimalPlaces - 1));
            }
            
            // Return the string-3 representation to preserve exact decimal places
            return rounded;
        } catch (error) {
            console.error('Coordinate normalization failed:', error);
            return null;
        }
    }

    function validateCoordinates(lat, lng) {
        // Normalize coordinates
        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 };
    }

    // Initialize map
    function initMap() {
        map = L.map('locationMap').setView([0, 0], 2);
        
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);

        // Initialize with existing coordinates if available
        const initialLat = document.getElementById('latitude').value;
        const initialLng = document.getElementById('longitude').value;
        if (initialLat && initialLng) {
            try {
                const normalized = validateCoordinates(initialLat, initialLng);
                addMarker(normalized.lat, normalized.lng);
            } catch (error) {
                console.error('Invalid initial coordinates:', error);
            }
        }

        // Handle map clicks
        map.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.');
            }
        });
    }

    // Initialize map
    initMap();

    // 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.street,
                                    result.city || (result.address && (result.address.city || result.address.town || result.address.village)),
                                    result.state || (result.address && (result.address.state || result.address.region)),
                                    result.country || (result.address && result.address.country),
                                    result.postal_code || (result.address && result.address.postcode)
                                ].filter(Boolean).join(', ')}
                            </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');
        }
    });

    function addMarker(lat, lng) {
        if (marker) {
            marker.remove();
        }
        marker = L.marker([lat, lng]).addTo(map);
        map.setView([lat, lng], 13);
    }

    function updateLocation(lat, lng, data) {
        try {
            const normalized = validateCoordinates(lat, lng);
            
            // Update coordinates
            document.getElementById('latitude').value = normalized.lat;
            document.getElementById('longitude').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').value = 
                `${address.house_number || ''} ${address.road || address.street || ''}`.trim() || '';
            document.getElementById('city').value = 
                address.city || address.town || address.village || '';
            document.getElementById('state').value = 
                address.state || address.region || '';
            document.getElementById('country').value = address.country || '';
            document.getElementById('postalCode').value = address.postcode || '';
        } 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.house_number || (result.address && result.address.house_number) || '',
                    road: result.street || (result.address && (result.address.road || result.address.street)) || '',
                    city: result.city || (result.address && (result.address.city || result.address.town || result.address.village)) || '',
                    state: result.state || (result.address && (result.address.state || result.address.region)) || '',
                    country: result.country || (result.address && result.address.country) || '',
                    postcode: result.postal_code || (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.');
        }
    }

    // Add form submit handler
    const form = document.querySelector('form');
    form.addEventListener('submit', function(e) {
        const lat = document.getElementById('latitude').value;
        const lng = document.getElementById('longitude').value;
        
        if (lat && lng) {
            try {
                validateCoordinates(lat, lng);
            } catch (error) {
                e.preventDefault();
                alert(error.message || 'Invalid coordinates. Please check the location.');
            }
        }
    });
});
</script>
