// Global State
let clientList = [];
let rawGeoJSON = null;
let prevGeoJSON = null;
let generatedGeoJSON = null;
let detectedClientCode = null;

// DOM Elements
const clientListInput = document.getElementById('clientListInput');
const rawGeoJSONInput = document.getElementById('rawGeoJSONInput');
const prevGeoJSONInput = document.getElementById('prevGeoJSONInput');
const clientSelect = document.getElementById('clientSelect');
const processBtn = document.getElementById('processBtn');
const downloadBtn = document.getElementById('downloadBtn');
const controlsSection = document.getElementById('controlsSection');
const diffViewer = document.getElementById('diffViewer');
const rawTableContainer = document.getElementById('rawTableContainer');
const editedTableContainer = document.getElementById('editedTableContainer');
const clearAllBtn = document.getElementById('clearAllBtn');

// Event Listeners
clientListInput.addEventListener('change', handleClientListUpload);
rawGeoJSONInput.addEventListener('change', handleRawGeoJSONUpload);
prevGeoJSONInput.addEventListener('change', handlePrevGeoJSONUpload);
processBtn.addEventListener('click', processGeoJSON);
downloadBtn.addEventListener('click', downloadGeoJSON);
clientSelect.addEventListener('change', () => {
    // If we have raw data, re-process or enable processing
    if (rawGeoJSON) {
        processBtn.disabled = false;
    }
});

// Clear All Logic
clearAllBtn.addEventListener('click', () => {
    if(confirm('Are you sure you want to clear all data and reset?')) {
        window.location.reload();
    }
});

// Helper: Attempt to match filename to client code
function tryAutoSelectClient(filename) {
    if (!filename) return;

    // 1. Always clear the current selection and detected code first
    clientSelect.value = "";
    detectedClientCode = null;

    // Matches strings starting with alphanumerics followed by an underscore OR a dot
    const match = filename.match(/^([A-Z0-9]+)[_.]/);
    
    if (match && match[1]) {
        const potentialCode = match[1];
        console.log(`Detected potential client code from filename: ${potentialCode}`);
        
        // Save this in case the client list is uploaded AFTER the GeoJSON
        detectedClientCode = potentialCode;

        // 2. Try to select it in the dropdown immediately if the list exists
        const option = Array.from(clientSelect.options).find(opt => opt.value === potentialCode);
        
        if (option) {
            clientSelect.value = potentialCode;
        } else {
            // Optional: Log that a code was found in the file, but not in the dropdown list yet
            console.log("Client code found in filename but not in the current list.");
        }
    }
}

// Helper: Parse Excel
function handleClientListUpload(e) {
    const file = e.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = function(e) {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, { type: 'array' });

        let sheetName = workbook.SheetNames.find(n => n === 'Client List') || workbook.SheetNames[0];
        const worksheet = workbook.Sheets[sheetName];
        const jsonData = XLSX.utils.sheet_to_json(worksheet);

        clientList = jsonData.map(row => ({
            country: row['Country'],
            name: row['Name'],
            code: row['SC-client-Code']
        })).filter(item => item.code);

        // Show count instead of filename
        document.getElementById('clientListStatus').textContent = `✓ ${clientList.length} clients uploaded`;
        
        populateClientDropdown();
        controlsSection.classList.remove('hidden');
    };
    reader.readAsArrayBuffer(file);
}

function populateClientDropdown() {
    clientSelect.innerHTML = '<option value="">-- Select Client --</option>';
    clientList.forEach(client => {
        const option = document.createElement('option');
        option.value = client.code;
        option.textContent = `${client.code} - ${client.name} (${client.country})`;
        clientSelect.appendChild(option);
    });
    
    // Attempt auto-selection if code was detected previously (e.g., from raw upload before client list)
    if (detectedClientCode) {
        const option = Array.from(clientSelect.options).find(opt => opt.value === detectedClientCode);
        if (option) {
            clientSelect.value = detectedClientCode;
        }
    }
}

// Helper: Parse GeoJSON
function handleRawGeoJSONUpload(e) {
    const file = e.target.files[0];
    if (!file) return;

    // Show filename
    document.getElementById('rawGeoJSONStatus').textContent = `Uploaded: ${file.name}`;
    
    // Try to detect client code from this filename
    tryAutoSelectClient(file.name);

    const reader = new FileReader();
    reader.onload = function(e) {
        try {
            rawGeoJSON = JSON.parse(e.target.result);
            renderTable(rawGeoJSON, rawTableContainer, false);
            
            // Clear the right column (edited view) when new raw file is uploaded
            editedTableContainer.innerHTML = '';
            
            // Reset generated GeoJSON and disable download
            generatedGeoJSON = null;
            downloadBtn.disabled = true;
            
            diffViewer.classList.remove('hidden');
            processBtn.disabled = false;
        } catch (err) {
            console.error('Error parsing GeoJSON:', err);
            alert('Error parsing Raw GeoJSON');
        }
    };
    reader.readAsText(file);
}

function handlePrevGeoJSONUpload(e) {
    const file = e.target.files[0];
    if (!file) return;

    // Show filename
    document.getElementById('prevGeoJSONStatus').textContent = `Uploaded: ${file.name}`;

    // Try to detect client code from this filename
    tryAutoSelectClient(file.name);

    const reader = new FileReader();
    reader.onload = function(e) {
        try {
            prevGeoJSON = JSON.parse(e.target.result);
            console.log("Previous GeoJSON loaded", prevGeoJSON);
        } catch (err) {
            console.error("Error parsing Previous GeoJSON", err);
            alert("Error parsing Previous GeoJSON");
        }
    };
    reader.readAsText(file);
}

// Core Logic: Generate IDs
function processGeoJSON() {
    if (!rawGeoJSON) {
        alert("Please upload Raw GeoJSON first.");
        return;
    }
    
    // Validate Client Selection for Prefix
    const clientCode = clientSelect.value;
    if (!clientCode) {
        alert("Please select a Client first to generate the correct ID format.");
        return;
    }

    // Helper to extract number from ID
    // Handles simple "0001" or complex "CODE_0001"
    const extractIdNumber = (idStr) => {
        if (!idStr) return 0;
        // Split by underscore and take the last segment
        const parts = String(idStr).split('_'); 
        const numPart = parts[parts.length - 1];
        const num = parseInt(numPart, 10);
        return isNaN(num) ? 0 : num;
    };

    // Determine max ID
    let maxId = 0;
    
    // 1. Scan Previous GeoJSON
    if (prevGeoJSON && prevGeoJSON.features) {
        prevGeoJSON.features.forEach(f => {
            if (f.properties && f.properties['sc_id']) {
                const num = extractIdNumber(f.properties['sc_id']);
                if (num > maxId) maxId = num;
            }
        });
    }

    // 2. Scan Raw GeoJSON (avoid collisions)
    if (rawGeoJSON && rawGeoJSON.features) {
        rawGeoJSON.features.forEach(f => {
            if (f.properties && f.properties['sc_id']) {
                const num = extractIdNumber(f.properties['sc_id']);
                if (num > maxId) maxId = num;
            }
        });
    }

    // Clone Raw GeoJSON to create Generated one
    generatedGeoJSON = JSON.parse(JSON.stringify(rawGeoJSON));
    
    let currentId = maxId;

    generatedGeoJSON.features.forEach(f => {
        if (!f.properties) f.properties = {};
        
        let existingId = f.properties['sc_id'];
        
        // Check if empty or missing
        if (existingId === undefined || existingId === null || existingId === "") {
            currentId++;
            // Format: CLIENTCODE_0001
            f.properties['sc_id'] = `${clientCode}_${String(currentId).padStart(4, '0')}`;
            f.isNew = true; // Flag for UI
        }
    });

    renderTable(generatedGeoJSON, editedTableContainer, true);
    downloadBtn.disabled = false;
}

function renderTable(geojson, container, isEdited) {
    if (!geojson || !geojson.features) return;

    container.innerHTML = '';
    const table = document.createElement('table');
    const thead = document.createElement('thead');
    const trHead = document.createElement('tr');
    ['Field', 'Subfield', 'SC_ID'].forEach(text => {
        const th = document.createElement('th');
        th.textContent = text;
        trHead.appendChild(th);
    });
    thead.appendChild(trHead);
    table.appendChild(thead);

    const tbody = document.createElement('tbody');
    
    geojson.features.forEach(f => {
        const props = f.properties || {};
        const field = props['field'] || '';
        const subfield = props['subfield'] || '';
        const scId = props['sc_id'] || '';
        
        const tr = document.createElement('tr');
        if (isEdited && f.isNew) {
            tr.className = 'diff-row new';
        }

        const tdField = document.createElement('td');
        tdField.textContent = field;
        tr.appendChild(tdField);

        const tdSubfield = document.createElement('td');
        tdSubfield.textContent = subfield;
        tr.appendChild(tdSubfield);

        const tdScId = document.createElement('td');
        tdScId.textContent = scId;
        tr.appendChild(tdScId);

        tbody.appendChild(tr);
    });
    
    table.appendChild(tbody);
    container.appendChild(table);
}

function downloadGeoJSON() {
    if (!generatedGeoJSON) return;
    
    // Remove temporary flags
    const cleanGeoJSON = JSON.parse(JSON.stringify(generatedGeoJSON));
    cleanGeoJSON.features.forEach(f => {
        delete f.isNew;
    });

    const clientCode = clientSelect.value || "UNKNOWN";
    const date = new Date();
    const dateStr = date.toISOString().split('T')[0]; // YYYY-MM-DD
    const filename = `${clientCode}_${dateStr}.geojson`;
    
    const blob = new Blob([JSON.stringify(cleanGeoJSON, null, 2)], { type: 'application/geo+json' });
    const url = URL.createObjectURL(blob);
    
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}