let map;
let osmLayer;
let satelliteLayer;

// Initialize map when DOM is ready
document.addEventListener('DOMContentLoaded', function() {
    // Initialize map layers
    osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors',
        maxNativeZoom: 19,
        maxZoom: 23
    });

    satelliteLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        attribution: '© Esri, DigitalGlobe, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community',
        maxNativeZoom: 18,
        maxZoom: 23
    });

    // Initialize map
    map = L.map('map', {
        maxZoom: 23,
        preferCanvas: true
    }).setView([0, 0], 2);
    osmLayer.addTo(map);

    // Invalidate map size to ensure proper rendering
    setTimeout(() => {
        map.invalidateSize();
    }, 100);

    // Initialize DOM elements
    csvInput = document.getElementById('csvFile');
    fileNameDisplay = document.getElementById('fileName');
    errorMessage = document.getElementById('errorMessage');
    successMessage = document.getElementById('successMessage');
    statsSection = document.getElementById('statsSection');
    featuresSection = document.getElementById('featuresSection');
    recordCountEl = document.getElementById('recordCount');
    columnCountEl = document.getElementById('columnCount');
    mappedCountEl = document.getElementById('mappedCount');
    featureLst = document.getElementById('featuresList');
    clearBtn = document.getElementById('clearBtn');
    downloadBtn = document.getElementById('downloadBtn');
    featureSearch = document.getElementById('featureSearch');
    polygonSection = document.getElementById('polygonSection');
    createPolygonsBtn = document.getElementById('createPolygonsBtn');
    downloadPolygonsBtn = document.getElementById('downloadPolygonsBtn');
    polygonCount = document.getElementById('polygonCount');

    // Setup event listeners
    csvInput.addEventListener('change', handleCsvUpload);
    clearBtn.addEventListener('click', handleClear);
    downloadBtn.addEventListener('click', handleDownload);
    featureSearch.addEventListener('input', handleSearch);
    createPolygonsBtn.addEventListener('click', handleCreatePolygons);
    downloadPolygonsBtn.addEventListener('click', handleDownloadPolygons);
});

let currentLayer = 'osm';
let markerLayer = null;
let polygonLayer = null;
let currentCsvData = null;
let featuresList = [];
let markers = [];
let selectedIndex = -1;
let currentPolygons = null;

// Toggle map layer
let mapToggle;
document.addEventListener('DOMContentLoaded', function() {
    mapToggle = document.getElementById('mapToggle');
    mapToggle.addEventListener('change', () => {
        if (mapToggle.checked) {
            map.removeLayer(currentLayer === 'osm' ? osmLayer : satelliteLayer);
            satelliteLayer.addTo(map);
            currentLayer = 'satellite';
        } else {
            map.removeLayer(currentLayer === 'satellite' ? satelliteLayer : osmLayer);
            osmLayer.addTo(map);
            currentLayer = 'osm';
        }
    });
});

// DOM Elements - will be initialized on DOMContentLoaded
let csvInput, fileNameDisplay, errorMessage, successMessage, statsSection, featuresSection;
let recordCountEl, columnCountEl, mappedCountEl, featureLst, clearBtn;
let downloadBtn, featureSearch, polygonSection, createPolygonsBtn, downloadPolygonsBtn, polygonCount;

// Show message
function showMessage(message, type = 'error') {
    const el = type === 'error' ? errorMessage : successMessage;
    el.textContent = message;
    el.classList.add('active');
    setTimeout(() => el.classList.remove('active'), 5000);
}

// Parse CSV text
function parseCSV(csvText) {
    const lines = csvText.trim().split('\n');
    if (lines.length === 0) return null;

    const headers = lines[0].split(',').map(h => h.trim());
    const data = [];

    for (let i = 1; i < lines.length; i++) {
        const fields = parseCSVLine(lines[i]);
        if (fields.length === 0) continue;

        const row = {};
        for (let j = 0; j < headers.length; j++) {
            row[headers[j]] = fields[j] || '';
        }
        data.push(row);
    }

    return { headers, data };
}

// Parse CSV line handling quoted values
function parseCSVLine(line) {
    const result = [];
    let current = '';
    let inQuotes = false;

    for (let i = 0; i < line.length; i++) {
        const char = line[i];
        const nextChar = line[i + 1];

        if (char === '"') {
            if (inQuotes && nextChar === '"') {
                current += '"';
                i++;
            } else {
                inQuotes = !inQuotes;
            }
        } else if (char === ',' && !inQuotes) {
            result.push(current);
            current = '';
        } else {
            current += char;
        }
    }
    result.push(current);
    return result;
}

// Find column by name (case-insensitive, handle underscores and spaces)
function findColumn(headers, searchName) {
    const normalized = searchName.toLowerCase().replace(/[\s_]/g, '');
    return headers.find(header => 
        header.toLowerCase().replace(/[\s_]/g, '') === normalized
    );
}

// Load CSV data
function loadCSV(csvData) {
    const { headers, data } = csvData;

    // Find required columns
    const latCol = findColumn(headers, 'start-geopoint-Latitude');
    const lonCol = findColumn(headers, 'start-geopoint-Longitude');
    const nameCol = findColumn(headers, 'field_id-field_name');
    const codeCol = findColumn(headers, 'field_id-field_code');

    if (!latCol || !lonCol) {
        showMessage('CSV must contain "start-geopoint-Latitude" and "start-geopoint-Longitude" columns');
        return false;
    }

    currentCsvData = { headers, data, latCol, lonCol, nameCol, codeCol };
    featuresList = [];
    markers = [];
    selectedIndex = -1;

    // Clear previous layer
    if (markerLayer) {
        map.removeLayer(markerLayer);
    }
    markerLayer = L.featureGroup();

    let mappedCount = 0;
    const bounds = L.latLngBounds();

    // Create markers
    data.forEach((row, index) => {
        const lat = parseFloat(row[latCol]);
        const lon = parseFloat(row[lonCol]);

        if (isNaN(lat) || isNaN(lon)) return;

        const fieldName = nameCol ? row[nameCol] : `Point ${index + 1}`;
        const fieldCode = codeCol ? row[codeCol] : '';

        const marker = L.circleMarker([lat, lon], {
            radius: 6,
            fillColor: '#667eea',
            color: '#4a5fc1',
            weight: 2,
            opacity: 0.8,
            fillOpacity: 0.7
        });

        // Create popup content
        const popupContent = `
            <div style="font-size: 13px; width: 280px;">
                <strong style="font-size: 14px; color: #333;">${fieldName}</strong>
                ${fieldCode ? `<br><small style="color: #666;">Code: ${fieldCode}</small>` : ''}
                <hr style="margin: 8px 0; border: none; border-top: 1px solid #eee;">
                <table style="width: 100%; font-size: 12px;">
                    <tr>
                        <td style="font-weight: 600; color: #333;">Latitude:</td>
                        <td>${lat.toFixed(6)}</td>
                    </tr>
                    <tr>
                        <td style="font-weight: 600; color: #333;">Longitude:</td>
                        <td>${lon.toFixed(6)}</td>
                    </tr>
                </table>
            </div>
        `;

        marker.bindPopup(popupContent);
        marker.on('click', () => selectFeature(index));

        markerLayer.addLayer(marker);
        bounds.extend([lat, lon]);

        featuresList.push({
            name: fieldName,
            code: fieldCode,
            lat,
            lon,
            index,
            row
        });

        mappedCount++;
    });

    // Add layer to map
    markerLayer.addTo(map);

    // Update stats
    recordCountEl.textContent = data.length;
    columnCountEl.textContent = headers.length;
    mappedCountEl.textContent = mappedCount;

    // Display features list
    displayFeaturesList();

    // Fit bounds
    if (mappedCount > 0) {
        map.fitBounds(bounds, { padding: [50, 50] });
    }

    // Show sections
    statsSection.style.display = 'block';
    featuresSection.style.display = 'block';
    polygonSection.style.display = 'block';
    downloadBtn.style.display = 'block';

    showMessage(`Successfully loaded ${mappedCount} field locations`, 'success');
    return true;
}

// Display features list
function displayFeaturesList() {
    featureLst.innerHTML = '';
    if (featuresList.length === 0) {
        featureLst.innerHTML = '<div style="padding: 8px; color: #999; text-align: center;">No features loaded</div>';
        return;
    }

    featuresList.forEach((feature, index) => {
        const item = document.createElement('div');
        item.className = 'feature-item' + (selectedIndex === index ? ' active' : '');
        item.innerHTML = `
            <strong>${feature.name}</strong>
            ${feature.code ? `<br><small style="color: #666;">Code: ${feature.code}</small>` : ''}
        `;
        item.addEventListener('click', () => selectFeature(index));
        featureLst.appendChild(item);
    });
}

// Select feature
function selectFeature(index) {
    selectedIndex = index;
    const feature = featuresList[index];

    // Update feature list highlight
    displayFeaturesList();

    // Zoom to marker
    map.setView([feature.lat, feature.lon], 16);
}





// Handle file upload
function handleCsvUpload(e) {
    const file = e.target.files[0];
    if (!file) return;

    fileNameDisplay.textContent = `📄 ${file.name}`;

    const reader = new FileReader();
    reader.onload = (event) => {
        try {
            const csvData = parseCSV(event.target.result);
            if (!csvData) {
                showMessage('Invalid CSV file');
                return;
            }
            loadCSV(csvData);
        } catch (err) {
            showMessage(`Error parsing CSV: ${err.message}`);
        }
    };
    reader.onerror = () => {
        showMessage('Error reading file');
    };
    reader.readAsText(file);
}

// Clear all
function handleClear() {
    csvInput.value = '';
    fileNameDisplay.textContent = 'No file selected';
    
    if (markerLayer) {
        map.removeLayer(markerLayer);
        markerLayer = null;
    }
    
    currentCsvData = null;
    featuresList = [];
    markers = [];
    selectedIndex = -1;

    statsSection.style.display = 'none';
    featuresSection.style.display = 'none';
    polygonSection.style.display = 'none';
    downloadBtn.style.display = 'none';
    downloadPolygonsBtn.style.display = 'none';

    if (polygonLayer) {
        map.removeLayer(polygonLayer);
        polygonLayer = null;
    }
    currentPolygons = null;

    showMessage('Data cleared', 'success');
}

// Download CSV
function handleDownload() {
    if (!currentCsvData) return;

    const { headers, data } = currentCsvData;
    let csv = headers.map(h => `"${h}"`).join(',') + '\n';
    
    data.forEach(row => {
        const values = headers.map(header => {
            const value = row[header] || '';
            return `"${String(value).replace(/"/g, '""')}"`;
        });
        csv += values.join(',') + '\n';
    });

    const blob = new Blob([csv], { type: 'text/csv' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'data.csv';
    a.click();
    window.URL.revokeObjectURL(url);

    showMessage('CSV downloaded', 'success');
}

// Search features
function handleSearch(e) {
    const searchTerm = e.target.value.toLowerCase();
    const items = document.querySelectorAll('.feature-item');
    
    items.forEach((item, index) => {
        const feature = featuresList[index];
        const match = feature.name.toLowerCase().includes(searchTerm) || 
                      feature.code.toLowerCase().includes(searchTerm);
        item.style.display = match ? 'block' : 'none';
    });
}

// Parse boundary string to coordinates
function parseBoundary(boundaryString) {
    if (!boundaryString || boundaryString.trim() === '') return null;
    
    const coordinates = [];
    const parts = boundaryString.split(';').map(p => p.trim()).filter(p => p.length > 0);
    
    for (const part of parts) {
        const values = part.split(/\s+/);
        if (values.length >= 2) {
            const lat = parseFloat(values[0]);
            const lon = parseFloat(values[1]);
            
            if (!isNaN(lat) && !isNaN(lon)) {
                // GeoJSON uses [longitude, latitude] format
                coordinates.push([lon, lat]);
            }
        }
    }
    
    // Close the polygon ring if not already closed
    if (coordinates.length > 0 && 
        (coordinates[0][0] !== coordinates[coordinates.length - 1][0] || 
         coordinates[0][1] !== coordinates[coordinates.length - 1][1])) {
        coordinates.push(coordinates[0]);
    }
    
    return coordinates.length > 3 ? [coordinates] : null;
}

// Create polygons from CSV data
function handleCreatePolygons() {
    if (!currentCsvData || !featuresList.length) {
        showMessage('No data loaded. Please upload a CSV file first.');
        return;
    }

    const { headers, data, latCol, lonCol, nameCol, codeCol } = currentCsvData;
    const boundaryCol = findColumn(headers, 'field_id-field_boundary');

    if (!boundaryCol) {
        showMessage('CSV does not contain "field_id-field_boundary" column');
        return;
    }

    // Clear previous polygons
    if (polygonLayer) {
        map.removeLayer(polygonLayer);
    }
    polygonLayer = L.featureGroup();

    const features = [];
    let polygonCount_val = 0;

    // Create polygons from boundary data
    data.forEach((row, index) => {
        const boundaryString = row[boundaryCol];
        const coordinates = parseBoundary(boundaryString);

        if (!coordinates) return;

        const fieldName = nameCol ? row[nameCol] : `Field ${index + 1}`;
        const fieldCode = codeCol ? row[codeCol] : '';

        // Create GeoJSON feature
        const feature = {
            type: 'Feature',
            geometry: {
                type: 'Polygon',
                coordinates: coordinates
            },
            properties: {
                name: fieldName,
                code: fieldCode,
                index: index
            }
        };

        features.push(feature);

        // Create Leaflet polygon
        const polygon = L.geoJSON(feature, {
            style: {
                color: '#667eea',
                weight: 2,
                opacity: 0.7,
                fillOpacity: 0.3
            },
            onEachFeature: (feature, layer) => {
                const popupContent = `
                    <div style="font-size: 13px;">
                        <strong>${feature.properties.name}</strong>
                        ${feature.properties.code ? `<br><small style="color: #666;">Code: ${feature.properties.code}</small>` : ''}
                    </div>
                `;
                layer.bindPopup(popupContent);
            }
        }).addTo(polygonLayer);

        polygonCount_val++;
    });

    // Add polygon layer to map
    polygonLayer.addTo(map);

    // Store polygons for download
    currentPolygons = {
        type: 'FeatureCollection',
        features: features
    };

    // Update count
    polygonCount.textContent = polygonCount_val;
    downloadPolygonsBtn.style.display = 'block';

    showMessage(`Successfully created ${polygonCount_val} polygons`, 'success');
}

// Download polygons as GeoJSON
function handleDownloadPolygons() {
    if (!currentPolygons) return;

    const geojsonString = JSON.stringify(currentPolygons, null, 2);
    const blob = new Blob([geojsonString], { type: 'application/json' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'polygons.geojson';
    a.click();
    window.URL.revokeObjectURL(url);

    showMessage('GeoJSON downloaded', 'success');
}
