// GigLez - Upload Functionality

let selectedFiles = [];
let autoDetectedGPS = null; // Store GPS detected from filenames

// Initialize upload functionality
document.addEventListener('DOMContentLoaded', () => {
    setupDropZone();
    setupFileInput();
});

// GPS Extraction from Filenames
// Matches patterns like: 34.0478N_118.2349W_1650_test_raw.sub
class GPSFilenameExtractor {
    constructor() {
        // Pattern 1: Decimal degrees with N/S/E/W (most common)
        this.PATTERN_NSEW = /(\d+\.?\d*)([NS])_(\d+\.?\d*)([EW])/i;

        // Pattern 2: lat/lon prefix format
        this.PATTERN_LATLON = /lat(-?\d+\.?\d+)lon(-?\d+\.?\d+)/i;

        // Pattern 3: Signed decimal degrees
        this.PATTERN_SIGNED = /(-?\d+\.?\d+)_(-?\d+\.?\d+)/;
    }

    extract(filename) {
        // Try each pattern
        let coords = this.tryNSEW(filename) ||
                    this.tryLatLon(filename) ||
                    this.trySigned(filename);

        return coords;
    }

    tryNSEW(filename) {
        const match = filename.match(this.PATTERN_NSEW);
        if (!match) return null;

        let lat = parseFloat(match[1]);
        let lon = parseFloat(match[3]);
        const latDir = match[2].toUpperCase();
        const lonDir = match[4].toUpperCase();

        // Apply direction (N=positive, S=negative, E=positive, W=negative)
        if (latDir === 'S') lat = -lat;
        if (lonDir === 'W') lon = -lon;

        if (!this.validateCoordinates(lat, lon)) return null;

        return {
            latitude: lat,
            longitude: lon,
            source: 'filename_nsew'
        };
    }

    tryLatLon(filename) {
        const match = filename.match(this.PATTERN_LATLON);
        if (!match) return null;

        const lat = parseFloat(match[1]);
        const lon = parseFloat(match[2]);

        if (!this.validateCoordinates(lat, lon)) return null;

        return {
            latitude: lat,
            longitude: lon,
            source: 'filename_latlon'
        };
    }

    trySigned(filename) {
        const match = filename.match(this.PATTERN_SIGNED);
        if (!match) return null;

        const lat = parseFloat(match[1]);
        const lon = parseFloat(match[2]);

        if (!this.validateCoordinates(lat, lon)) return null;

        return {
            latitude: lat,
            longitude: lon,
            source: 'filename_signed'
        };
    }

    validateCoordinates(lat, lon) {
        return lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180;
    }
}

const gpsExtractor = new GPSFilenameExtractor();

function setupDropZone() {
    const dropZone = document.getElementById('drop-zone');

    dropZone.addEventListener('click', () => {
        document.getElementById('file-input').click();
    });

    dropZone.addEventListener('dragover', (e) => {
        e.preventDefault();
        dropZone.classList.add('drag-over');
    });

    dropZone.addEventListener('dragleave', () => {
        dropZone.classList.remove('drag-over');
    });

    dropZone.addEventListener('drop', (e) => {
        e.preventDefault();
        dropZone.classList.remove('drag-over');

        const files = Array.from(e.dataTransfer.files).filter(f => f.name.endsWith('.sub'));
        addFiles(files);
    });
}

function setupFileInput() {
    const fileInput = document.getElementById('file-input');

    fileInput.addEventListener('change', (e) => {
        const files = Array.from(e.target.files);
        addFiles(files);
    });
}

function addFiles(files) {
    if (files.length === 0) {
        alert('Please select .sub files');
        return;
    }

    // Add new files
    selectedFiles.push(...files);

    // Try to extract GPS from first file with coordinates
    if (!autoDetectedGPS) {
        for (const file of files) {
            const coords = gpsExtractor.extract(file.name);
            if (coords) {
                autoDetectedGPS = coords;
                // Auto-populate GPS fields
                document.getElementById('default-lat').value = coords.latitude.toFixed(6);
                document.getElementById('default-lon').value = coords.longitude.toFixed(6);

                // Show notification
                showGPSDetectionNotification(file.name, coords);
                break;
            }
        }
    }

    // Show file list
    document.getElementById('file-list').style.display = 'block';

    // Render file list
    renderFileList();
}

function showGPSDetectionNotification(filename, coords) {
    const notification = document.createElement('div');
    notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: #10b981;
        color: white;
        padding: 1rem 1.5rem;
        border-radius: 0.5rem;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        z-index: 10000;
        max-width: 400px;
        animation: slideIn 0.3s ease-out;
    `;

    notification.innerHTML = `
        <strong>📍 GPS Auto-Detected!</strong><br>
        <small>From: ${filename}</small><br>
        <small>Coordinates: ${coords.latitude.toFixed(6)}, ${coords.longitude.toFixed(6)}</small>
    `;

    document.body.appendChild(notification);

    // Add animation
    const style = document.createElement('style');
    style.textContent = `
        @keyframes slideIn {
            from { transform: translateX(400px); opacity: 0; }
            to { transform: translateX(0); opacity: 1; }
        }
    `;
    document.head.appendChild(style);

    // Remove after 5 seconds
    setTimeout(() => {
        notification.style.animation = 'slideIn 0.3s ease-out reverse';
        setTimeout(() => notification.remove(), 300);
    }, 5000);
}

function renderFileList() {
    const container = document.getElementById('files-container');

    container.innerHTML = selectedFiles.map((file, index) => {
        const coords = gpsExtractor.extract(file.name);
        const hasGPS = coords !== null;

        return `
            <div class="file-item" data-index="${index}">
                <div class="file-info">
                    <div class="file-name">
                        ${file.name}
                        ${hasGPS ? '<span style="color: #10b981; margin-left: 0.5rem;">📍 GPS</span>' : ''}
                    </div>
                    <div class="file-meta">
                        ${formatFileSize(file.size)}
                        ${hasGPS ? ` | ${coords.latitude.toFixed(4)}, ${coords.longitude.toFixed(4)}` : ''}
                    </div>
                </div>
                <div class="file-actions">
                    <button type="button" class="btn btn-secondary" onclick="removeFile(${index})">Remove</button>
                </div>
            </div>
        `;
    }).join('');
}

function removeFile(index) {
    selectedFiles.splice(index, 1);

    if (selectedFiles.length === 0) {
        document.getElementById('file-list').style.display = 'none';
    } else {
        renderFileList();
    }
}

function clearFiles() {
    selectedFiles = [];
    autoDetectedGPS = null; // Reset auto-detected GPS
    document.getElementById('file-list').style.display = 'none';
    document.getElementById('file-input').value = '';
}

async function uploadFiles() {
    if (selectedFiles.length === 0) {
        alert('Please select files to upload');
        return;
    }

    // Validate GPS coordinates (allow auto-detected or manual entry)
    const lat = parseFloat(document.getElementById('default-lat').value);
    const lon = parseFloat(document.getElementById('default-lon').value);

    if (isNaN(lat) || isNaN(lon)) {
        // Check if any file has GPS in filename
        const hasGPSInFilename = selectedFiles.some(file => gpsExtractor.extract(file.name) !== null);

        if (hasGPSInFilename) {
            alert('GPS detected in filename but not populated. Please refresh and try again.');
        } else {
            alert('Please provide GPS coordinates (manually or via filename like: 34.0478N_118.2349W_filename.sub)');
        }
        return;
    }

    if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {
        alert('GPS coordinates out of range');
        return;
    }

    // Hide file list, show progress
    document.getElementById('file-list').style.display = 'none';
    document.getElementById('upload-progress').style.display = 'block';

    try {
        // Build manifest
        const sessionUuid = document.getElementById('session-uuid').value || generateUUID();
        const accuracy = parseFloat(document.getElementById('default-accuracy').value) || 5.0;
        const altitude = parseFloat(document.getElementById('default-altitude').value) || null;

        const manifest = {
            session_uuid: sessionUuid,
            captures: selectedFiles.map(file => ({
                filename: file.name,
                latitude: lat,
                longitude: lon,
                accuracy: accuracy,
                altitude: altitude,
                timestamp: new Date().toISOString()
            }))
        };

        // Build FormData
        const formData = new FormData();
        formData.append('manifest', JSON.stringify(manifest));

        selectedFiles.forEach(file => {
            formData.append('files', file);
        });

        // Upload
        updateProgress(0, 'Uploading files...');

        const response = await fetch('/api/v1/captures/upload', {
            method: 'POST',
            body: formData
        });

        updateProgress(100, 'Processing...');

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.detail || 'Upload failed');
        }

        const result = await response.json();

        // Show results
        showUploadResults(result);

    } catch (error) {
        console.error('Upload error:', error);
        alert(`Upload failed: ${error.message}`);

        // Reset
        document.getElementById('upload-progress').style.display = 'none';
        document.getElementById('file-list').style.display = 'block';
    }
}

function updateProgress(percent, text) {
    document.getElementById('progress-fill').style.width = `${percent}%`;
    document.getElementById('progress-text').textContent = text;
}

function showUploadResults(result) {
    // Hide progress
    document.getElementById('upload-progress').style.display = 'none';

    // Show results
    const resultsDiv = document.getElementById('upload-results');
    const container = document.getElementById('results-container');

    resultsDiv.style.display = 'block';

    const successCount = result.successful?.length || 0;
    const errorCount = result.failed?.length || 0;

    let html = `
        <div class="result-summary">
            <p>Successfully uploaded: <strong>${successCount}</strong> files</p>
            ${errorCount > 0 ? `<p>Failed: <strong>${errorCount}</strong> files</p>` : ''}
        </div>
    `;

    if (result.successful && result.successful.length > 0) {
        html += '<h4>Successful Uploads:</h4>';
        result.successful.forEach(item => {
            html += `
                <div class="result-item">
                    <div class="file-name">${item.filename}</div>
                    <div class="file-meta">
                        Frequency: ${(item.frequency / 1e6).toFixed(2)} MHz |
                        Protocol: ${item.protocol || 'RAW'}
                    </div>
                </div>
            `;
        });
    }

    if (result.failed && result.failed.length > 0) {
        html += '<h4>Failed Uploads:</h4>';
        result.failed.forEach(item => {
            html += `
                <div class="result-item error">
                    <div class="file-name">${item.filename}</div>
                    <div class="file-meta">Error: ${item.error}</div>
                </div>
            `;
        });
    }

    container.innerHTML = html;
}

function resetUpload() {
    // Hide results
    document.getElementById('upload-results').style.display = 'none';

    // Clear files
    clearFiles();

    // Reset form
    document.getElementById('default-lat').value = '';
    document.getElementById('default-lon').value = '';
    document.getElementById('session-uuid').value = '';

    // Reset auto-detected GPS
    autoDetectedGPS = null;
}

function useCurrentLocation() {
    if (!navigator.geolocation) {
        alert('Geolocation is not supported by your browser');
        return;
    }

    navigator.geolocation.getCurrentPosition(
        (position) => {
            document.getElementById('default-lat').value = position.coords.latitude.toFixed(6);
            document.getElementById('default-lon').value = position.coords.longitude.toFixed(6);
            document.getElementById('default-accuracy').value = position.coords.accuracy.toFixed(1);

            if (position.coords.altitude) {
                document.getElementById('default-altitude').value = position.coords.altitude.toFixed(1);
            }
        },
        (error) => {
            alert(`Geolocation error: ${error.message}`);
        }
    );
}

function generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = Math.random() * 16 | 0;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

function formatFileSize(bytes) {
    if (bytes < 1024) return bytes + ' B';
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
    return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}
