const MARINE_API   = API_URL + '/marine';
const MAPBOX_TOKEN = 'pk.eyJ1Ijoic2VzZWUzIiwiYSI6ImNtZ2dydndkMDBsNjUya3NjeW91dW41MzcifQ.M2qxj0wL1W7plRzIataojQ';

// ── State ──────────────────────────────────────────────────────────────────
let selectedDatasetId = null;
let selectedVariables = new Set();
let datasetDateRange  = { min: null, max: null };
let tags              = ['marine'];
let currentBbox       = null;
let currentStep       = 0;
let map               = null;
let isDrawMode        = false;
let isDrawing         = false;
let drawStart         = null;
let pollInterval      = null;
const TOTAL_STEPS     = 6;

// Variable renames: { originalName: customName }
let variableRenames   = {};
let _currentRenaming  = null;

// ── Init ───────────────────────────────────────────────────────────────────
document.addEventListener('DOMContentLoaded', () => {
    initMap();
    renderTags();
    setupTagInput();
    renderDots();
    showStep(0, false);

    document.getElementById('catalogSearch').addEventListener('keydown', e => {
        if (e.key === 'Enter') searchCatalog();
    });

    document.getElementById('renameInput').addEventListener('keydown', e => {
        if (e.key === 'Enter') { e.preventDefault(); saveRename(); }
        if (e.key === 'Escape') closeRenameModal();
    });

    ['startDate','endDate','datasetName','outputFormat'].forEach(id => {
        const el = document.getElementById(id);
        if (el) el.addEventListener('change', () => { markDone(); updateSummary(); refreshNext(); });
    });
});

// ── Stepper ────────────────────────────────────────────────────────────────
function showStep(i, smooth = true) {
    const steps = Array.from(document.querySelectorAll('.step'));
    currentStep = Math.max(0, Math.min(i, TOTAL_STEPS - 1));

    steps.forEach((el, idx) => {
        const active = idx === currentStep;
        el.classList.toggle('active', active);
        if (active) el.removeAttribute('disabled');
        else el.setAttribute('disabled', '');
    });

    document.getElementById('prevBtn').disabled = currentStep === 0;
    document.getElementById('nextBtn').textContent = currentStep === TOTAL_STEPS - 1 ? 'Fine' : 'Prossimo';
    refreshNext();
    updateDots();
    updateSummary();
    markDone();

    if (smooth) {
        const active = steps[currentStep];
        if (active) setTimeout(() => active.scrollIntoView({ behavior: 'smooth', block: 'center' }), 60);
    }
}

function refreshNext() {
    document.getElementById('nextBtn').disabled = !canAdvance(currentStep);
}

function nextStep() {
    if (!canAdvance(currentStep)) { showToast('Completa questo passo per continuare', 'error'); return; }
    if (currentStep < TOTAL_STEPS - 1) showStep(currentStep + 1);
}

function prevStep() {
    if (currentStep > 0) showStep(currentStep - 1);
}

function canAdvance(i) {
    switch (i) {
        case 0: return !!selectedDatasetId;
        case 1: return selectedVariables.size > 0;
        case 2: return !!currentBbox;
        case 3: {
            const s = document.getElementById('startDate').value;
            const e = document.getElementById('endDate').value;
            return !!(s && e && s <= e);
        }
        case 4: return !!document.getElementById('datasetName').value.trim();
        default: return true;
    }
}

// ── Dots ───────────────────────────────────────────────────────────────────
function renderDots() {
    const c = document.getElementById('progressDots');
    c.innerHTML = '';
    for (let i = 0; i < TOTAL_STEPS; i++) {
        const d = document.createElement('button');
        d.className = 'progress-dot';
        d.setAttribute('aria-label', `Passo ${i + 1}`);
        d.addEventListener('click', () => { if (i <= currentStep) showStep(i); });
        c.appendChild(d);
    }
    updateDots();
}

function updateDots() {
    Array.from(document.getElementById('progressDots').children)
        .forEach((d, i) => d.classList.toggle('active', i === currentStep));
}

// ── Done badges ────────────────────────────────────────────────────────────
function markDone() {
    const steps = document.querySelectorAll('.step');
    const checks = [
        !!selectedDatasetId,
        selectedVariables.size > 0,
        !!currentBbox,
        canAdvance(3),
        !!document.getElementById('datasetName').value.trim(),
        false,
    ];
    steps.forEach((el, i) => el.classList.toggle('done', checks[i] === true));
}

// ── Catalog ────────────────────────────────────────────────────────────────
async function searchCatalog() {
    const q   = document.getElementById('catalogSearch').value.trim();
    const btn = document.getElementById('searchBtn');
    const box = document.getElementById('catalogResults');

    box.innerHTML = '<div class="catalog-empty"><span class="spin"></span>Ricerca in corso...</div>';
    btn.disabled = true;

    try {
        const params = q ? `?search=${encodeURIComponent(q)}&limit=30` : '?limit=30';
        const res    = await MEB_AUTH.fetch(`${MARINE_API}/catalog${params}`);
        const data   = await res.json();

        if (!res.ok) throw new Error(data.detail || 'Errore catalogo');

        if (!data.datasets?.length) {
            box.innerHTML = '<div class="catalog-empty">Nessun dataset trovato</div>';
            return;
        }

        box.innerHTML = '';
        data.datasets.forEach(ds => {
            const item = document.createElement('div');
            item.className = 'catalog-item';
            item.innerHTML = `<div class="ds-id">${ds.dataset_id}</div><div class="ds-title">${ds.title || ''}</div>`;
            item.addEventListener('click', () => selectDataset(ds, item));
            box.appendChild(item);
        });
    } catch (e) {
        box.innerHTML = `<div class="catalog-empty" style="color:var(--danger)">Errore: ${e.message}</div>`;
    } finally {
        btn.disabled = false;
    }
}

async function selectDataset(ds, itemEl) {
    document.querySelectorAll('.catalog-item').forEach(i => i.classList.remove('selected'));
    itemEl.classList.add('selected');
    selectedDatasetId = ds.dataset_id;

    const badge = document.getElementById('selectedDsBadge');
    badge.textContent = ds.dataset_id;
    badge.style.display = 'block';

    // Reset dependent steps
    selectedVariables.clear();
    const vBox = document.getElementById('variablesContainer');
    vBox.innerHTML = '<span class="spin"></span><span style="color:var(--text-secondary);font-size:0.85rem;">Caricamento variabili...</span>';

    try {
        const res  = await MEB_AUTH.fetch(`${MARINE_API}/catalog/${encodeURIComponent(ds.dataset_id)}`);
        const info = await res.json();

        renderVariables(info.variables || ds.variables || []);

        if (info.min_longitude != null) {
            setBboxAndFit(info.min_longitude, info.max_longitude, info.min_latitude, info.max_latitude);
        }

        if (info.start_datetime) {
            prefillDates(info.start_datetime, info.end_datetime);
        }
    } catch {
        renderVariables(ds.variables || []);
    }

    markDone();
    refreshNext();
    // Auto-advance to variables step
    setTimeout(() => showStep(1), 700);
}

// ── Variables ──────────────────────────────────────────────────────────────
function renderVariables(vars) {
    const c = document.getElementById('variablesContainer');
    if (!vars?.length) {
        c.innerHTML = '<span style="color:var(--text-secondary);font-size:0.85rem;">Nessuna variabile disponibile</span>';
        updateVarCount();
        return;
    }

    c.innerHTML = '';
    vars.forEach(v => {
        const name  = typeof v === 'string' ? v : v.short_name;
        const desc  = typeof v === 'object' ? (v.description || v.standard_name || '') : '';
        const units = typeof v === 'object' && v.units ? v.units : '';

        const chip = document.createElement('div');
        chip.className = 'var-chip';
        chip.dataset.name = name;
        chip.innerHTML = `
            <span class="var-name">${esc(name)}</span>
            ${desc  ? `<span class="var-desc" title="${esc(desc)}">${esc(desc)}</span>` : ''}
            ${units ? `<span class="var-units">[${esc(units)}]</span>` : ''}
            <button class="rename-btn" onclick="event.stopPropagation(); openRenameModal(this.closest('.var-chip').dataset.name)">✏ Rinomina</button>
            <span class="rename-badge">${variableRenames[name] ? '→ ' + esc(variableRenames[name]) : ''}</span>
        `;
        chip.addEventListener('click', () => toggleVar(chip, name));
        c.appendChild(chip);
    });

    updateVarCount();
}

function toggleVar(chip, name) {
    if (selectedVariables.has(name)) { selectedVariables.delete(name); chip.classList.remove('selected'); }
    else                              { selectedVariables.add(name);    chip.classList.add('selected'); }
    updateVarCount(); markDone(); refreshNext();
}

function updateVarCount() {
    const n = selectedVariables.size;
    document.getElementById('varCount').textContent =
        n === 0 ? 'Nessuna selezionata' : `${n} selezionat${n === 1 ? 'a' : 'e'}`;
}

function selectAllVars() {
    document.querySelectorAll('.var-chip').forEach(chip => {
        chip.classList.add('selected');
        selectedVariables.add(chip.dataset.name);
    });
    updateVarCount(); markDone(); refreshNext();
}

function deselectAllVars() {
    document.querySelectorAll('.var-chip').forEach(chip => chip.classList.remove('selected'));
    selectedVariables.clear();
    updateVarCount(); markDone(); refreshNext();
}

// ── Dates ──────────────────────────────────────────────────────────────────
function prefillDates(minDate, maxDate) {
    datasetDateRange = { min: minDate, max: maxDate };
    const s = document.getElementById('startDate');
    const e = document.getElementById('endDate');

    if (minDate) { s.min = minDate; s.value = minDate; e.min = minDate; }
    if (maxDate) { e.max = maxDate; e.value = maxDate; s.max = maxDate; }

    const hint = document.getElementById('dateRangeHint');
    if (minDate && maxDate) hint.textContent = `Dati disponibili: ${minDate} → ${maxDate}`;

    markDone(); updateSummary();
}

// ── Map ────────────────────────────────────────────────────────────────────
function initMap() {
    mapboxgl.accessToken = MAPBOX_TOKEN;
    map = new mapboxgl.Map({
        container: 'mapContainer',
        style: 'mapbox://styles/mapbox/dark-v11',
        center: [14, 42], zoom: 3.5,
        attributionControl: false,
    });
    map.addControl(new mapboxgl.NavigationControl({ showCompass: false }), 'top-right');
    map.addControl(new mapboxgl.AttributionControl({ compact: true }), 'bottom-right');

    map.on('load', () => {
        map.addSource('bbox-rect', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
        map.addLayer({ id: 'bbox-fill', type: 'fill',   source: 'bbox-rect', paint: { 'fill-color': '#00a7f5', 'fill-opacity': 0.13 } });
        map.addLayer({ id: 'bbox-line', type: 'line',   source: 'bbox-rect', paint: { 'line-color': '#00a7f5', 'line-width': 2, 'line-dasharray': [4, 2] } });
    });

    map.getCanvas().addEventListener('mousedown', onCanvasMouseDown, true);
    window.addEventListener('mousemove', onWindowMouseMove);
    window.addEventListener('mouseup',   onWindowMouseUp);
}

function startDraw() {
    if (!map) return;
    isDrawMode = true;
    map.dragPan.disable(); map.boxZoom.disable();
    document.getElementById('mapContainer').classList.add('draw-mode');
    const btn = document.getElementById('drawBtn');
    btn.textContent = 'Clicca e trascina…';
    btn.classList.replace('secondary', 'primary');
}

function exitDrawMode() {
    isDrawMode = isDrawing = false; drawStart = null;
    map.dragPan.enable(); map.boxZoom.enable();
    document.getElementById('mapContainer').classList.remove('draw-mode', 'drawing');
    const btn = document.getElementById('drawBtn');
    btn.textContent = 'Disegna area';
    btn.classList.replace('primary', 'secondary');
}

function onCanvasMouseDown(e) {
    if (!isDrawMode) return;
    e.preventDefault(); e.stopPropagation();
    isDrawing = true;
    drawStart = map.unproject([e.offsetX, e.offsetY]);
    document.getElementById('mapContainer').classList.add('drawing');
}

function onWindowMouseMove(e) {
    if (!isDrawing || !drawStart) return;
    const rc = map.getCanvas().getBoundingClientRect();
    _drawRect(drawStart, map.unproject([e.clientX - rc.left, e.clientY - rc.top]));
}

function onWindowMouseUp(e) {
    if (!isDrawing || !drawStart) return;
    const rc  = map.getCanvas().getBoundingClientRect();
    const end = map.unproject([e.clientX - rc.left, e.clientY - rc.top]);
    setBbox(
        Math.min(drawStart.lng, end.lng), Math.max(drawStart.lng, end.lng),
        Math.min(drawStart.lat, end.lat), Math.max(drawStart.lat, end.lat)
    );
    exitDrawMode();
}

function _drawRect(a, b) {
    if (!map.getSource('bbox-rect')) return;
    map.getSource('bbox-rect').setData({
        type: 'Feature',
        geometry: { type: 'Polygon', coordinates: [[[a.lng,a.lat],[b.lng,a.lat],[b.lng,b.lat],[a.lng,b.lat],[a.lng,a.lat]]] },
    });
}

function setBbox(minLon, maxLon, minLat, maxLat) {
    currentBbox = { minLon, maxLon, minLat, maxLat };
    document.getElementById('minLon').value = minLon.toFixed(4);
    document.getElementById('maxLon').value = maxLon.toFixed(4);
    document.getElementById('minLat').value = minLat.toFixed(4);
    document.getElementById('maxLat').value = maxLat.toFixed(4);
    document.getElementById('bboxReadout').textContent =
        `${minLon.toFixed(2)}°/${minLat.toFixed(2)}° → ${maxLon.toFixed(2)}°/${maxLat.toFixed(2)}°`;
    _drawRect({ lng: minLon, lat: minLat }, { lng: maxLon, lat: maxLat });
    markDone(); refreshNext();
}

function setBboxAndFit(minLon, maxLon, minLat, maxLat) {
    const doIt = () => {
        setBbox(minLon, maxLon, minLat, maxLat);
        map.fitBounds([[minLon, minLat], [maxLon, maxLat]], { padding: 40, maxZoom: 10, duration: 600 });
    };
    if (!map) return;
    if (map.isStyleLoaded()) doIt(); else map.once('load', doIt);
}

function clearBbox() {
    currentBbox = null;
    ['minLon','maxLon','minLat','maxLat'].forEach(id => document.getElementById(id).value = '');
    document.getElementById('bboxReadout').textContent = '';
    if (map?.getSource('bbox-rect')) map.getSource('bbox-rect').setData({ type: 'FeatureCollection', features: [] });
    markDone(); refreshNext();
}

// ── Tags ───────────────────────────────────────────────────────────────────
function setupTagInput() {
    const inp = document.getElementById('tagInput');
    inp.addEventListener('keydown', e => {
        if ((e.key === 'Enter' || e.key === ',') && inp.value.trim()) {
            e.preventDefault();
            const t = inp.value.trim().replace(/,/g,'').toLowerCase();
            if (t && !tags.includes(t)) { tags.push(t); renderTags(); }
            inp.value = '';
        } else if (e.key === 'Backspace' && !inp.value && tags.length) {
            tags.pop(); renderTags();
        }
    });
}

function renderTags() {
    const wrap = document.getElementById('tagsWrap');
    const inp  = document.getElementById('tagInput');
    wrap.innerHTML = '';
    tags.forEach(t => {
        const chip = document.createElement('span');
        chip.className = 'tag-chip';
        chip.innerHTML = `${t} <span class="rm" onclick="removeTag('${t}')">×</span>`;
        wrap.appendChild(chip);
    });
    wrap.appendChild(inp);
}

function removeTag(t) { tags = tags.filter(x => x !== t); renderTags(); }

// ── Download ───────────────────────────────────────────────────────────────
async function startDownload() {
    if (!selectedDatasetId)                                    return showToast('Seleziona un dataset', 'error');
    if (!selectedVariables.size)                               return showToast('Seleziona almeno una variabile', 'error');
    if (!currentBbox)                                          return showToast("Disegna un'area sulla mappa", 'error');
    if (!document.getElementById('startDate').value ||
        !document.getElementById('endDate').value)             return showToast('Inserisci le date', 'error');
    if (!document.getElementById('datasetName').value.trim()) return showToast('Inserisci un nome', 'error');

    const body = {
        dataset_id:    selectedDatasetId,
        variables:     Array.from(selectedVariables),
        min_longitude: parseFloat(document.getElementById('minLon').value),
        max_longitude: parseFloat(document.getElementById('maxLon').value),
        min_latitude:  parseFloat(document.getElementById('minLat').value),
        max_latitude:  parseFloat(document.getElementById('maxLat').value),
        start_date:    document.getElementById('startDate').value,
        end_date:      document.getElementById('endDate').value,
        format:        document.getElementById('outputFormat').value,
        nome:             document.getElementById('datasetName').value.trim(),
        tags:             [...tags],
        notes:            document.getElementById('datasetNotes').value.trim(),
        variable_renames: { ...variableRenames },
    };

    const btn  = document.getElementById('downloadBtn');
    const prog = document.getElementById('downloadProgress');
    btn.disabled = true;
    prog.style.display = 'block';
    setProgress(0, 'Avvio download...');

    try {
        const res  = await MEB_AUTH.fetch(`${MARINE_API}/jobs`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(body),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.detail || 'Errore avvio job');
        pollJob(data.job_id, btn, prog);
    } catch (e) {
        showToast(`Errore: ${e.message}`, 'error');
        btn.disabled = false;
        prog.style.display = 'none';
    }
}

function pollJob(jobId, btn, prog) {
    clearInterval(pollInterval);
    pollInterval = setInterval(async () => {
        try {
            const res = await MEB_AUTH.fetch(`${MARINE_API}/jobs/${jobId}`);
            const job = await res.json();
            setProgress(job.progress, job.message);

            if (job.status === 'done') {
                clearInterval(pollInterval);
                btn.disabled = false;
                showToast('Dataset salvato con successo!', 'success');
                setTimeout(resetAll, 1800);
            } else if (job.status === 'error') {
                clearInterval(pollInterval);
                btn.disabled = false;
                showToast(`Errore: ${job.message}`, 'error');
                prog.style.display = 'none';
            }
        } catch { /* transient */ }
    }, 2000);
}

function setProgress(pct, msg) {
    document.getElementById('progressFill').style.width = pct + '%';
    document.getElementById('progressMsg').textContent  = msg;
}

// ── Reset ──────────────────────────────────────────────────────────────────
function resetAll() {
    selectedDatasetId = null;
    selectedVariables.clear();
    datasetDateRange  = { min: null, max: null };
    variableRenames   = {};
    tags              = ['marine'];

    ['startDate','endDate','datasetName','datasetNotes'].forEach(id => {
        const el = document.getElementById(id);
        if (el) { el.value = ''; el.min = ''; el.max = ''; }
    });

    document.getElementById('catalogResults').innerHTML =
        '<div class="catalog-empty">Cerca un dataset Copernicus per iniziare</div>';
    document.getElementById('selectedDsBadge').style.display = 'none';
    document.getElementById('variablesContainer').innerHTML =
        '<span style="color:var(--text-secondary);font-size:0.85rem;">Seleziona un dataset per vedere le variabili</span>';
    document.getElementById('dateRangeHint').textContent = '';
    document.getElementById('downloadProgress').style.display = 'none';

    clearBbox();
    renderTags();
    showStep(0);
}

// ── Summary ────────────────────────────────────────────────────────────────
function updateSummary() {
    if (currentStep !== 5) return;
    const s    = document.getElementById('startDate').value  || '-';
    const e    = document.getElementById('endDate').value    || '-';
    const name = document.getElementById('datasetName').value || '-';
    const fmt  = document.getElementById('outputFormat').value || '-';
    const vars = Array.from(selectedVariables).join(', ')    || '-';
    const bbox = currentBbox
        ? `${currentBbox.minLon.toFixed(2)},${currentBbox.minLat.toFixed(2)} → ${currentBbox.maxLon.toFixed(2)},${currentBbox.maxLat.toFixed(2)}`
        : '-';
    document.getElementById('summaryContent').innerHTML = `
        <div><strong>Dataset:</strong> ${esc(selectedDatasetId || '-')}</div>
        <div><strong>Variabili (${selectedVariables.size}):</strong> ${esc(vars)}</div>
        <div><strong>Area:</strong> ${esc(bbox)}</div>
        <div><strong>Periodo:</strong> ${esc(s)} → ${esc(e)}</div>
        <div><strong>Formato:</strong> ${esc(fmt)}</div>
        <div><strong>Nome:</strong> ${esc(name)}</div>
        <div><strong>Tags:</strong> ${esc(tags.join(', '))}</div>
    `;
}

// ── Rename modal ───────────────────────────────────────────────────────────
function openRenameModal(varName) {
    _currentRenaming = varName;
    document.getElementById('renameVarLabel').textContent = varName;
    document.getElementById('renameInput').value = variableRenames[varName] || '';
    document.getElementById('renameDeleteBtn').style.display = variableRenames[varName] ? 'inline-flex' : 'none';
    document.getElementById('renameModal').classList.add('visible');
    setTimeout(() => document.getElementById('renameInput').select(), 50);
}

function saveRename() {
    if (!_currentRenaming) return;
    const val = document.getElementById('renameInput').value.trim();
    if (!val) { deleteRename(); return; }
    variableRenames[_currentRenaming] = val;
    _updateRenameBadge(_currentRenaming, val);
    closeRenameModal();
}

function deleteRename() {
    if (!_currentRenaming) return;
    delete variableRenames[_currentRenaming];
    _updateRenameBadge(_currentRenaming, '');
    closeRenameModal();
}

function closeRenameModal() {
    document.getElementById('renameModal').classList.remove('visible');
    _currentRenaming = null;
}

function _updateRenameBadge(varName, text) {
    const chip = [...document.querySelectorAll('.var-chip')].find(c => c.dataset.name === varName);
    if (!chip) return;
    chip.querySelector('.rename-badge').textContent = text ? '→ ' + text : '';
}

// ── Helpers ────────────────────────────────────────────────────────────────
function esc(s) {
    return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

function showToast(msg, type = 'success') {
    const t = document.getElementById('toast');
    t.className = `${type} show`;
    t.textContent = msg;
    setTimeout(() => t.classList.remove('show'), 3500);
}