/**
 * Lógica del Visor Médico Offline con soporte DICOM (Cornerstone)
 * v2.0 - Con navegación completa, atajos de teclado y gestos táctiles
 */

let currentZoom = 1;
let currentRotation = 0;
let currentBrightness = 100;
let currentContrast = 100;
let currentInvert = 0;

let imagenes = [];
let indiceActual = 0;
let esDicomActual = false;

// Pan (arrastrar imagen)
let isPanning = false;
let panStartX = 0, panStartY = 0;
let offsetX = 0, offsetY = 0;

// ===================== INIT CORNERSTONE =====================
function initCornerstone() {
    if (typeof cornerstoneWADOImageLoader !== 'undefined') {
        cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
        cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
        const config = {
            webWorkerPath: 'js/lib/cornerstoneWADOImageLoaderWebWorker.min.js',
            taskConfiguration: {
                decodeTask: { codecsPath: 'js/lib/cornerstoneWADOImageLoaderCodecs.min.js' }
            }
        };
        cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
        const element = document.getElementById('dicom-viewer');
        cornerstone.enable(element);
    }
}

// ===================== VARIABLES GLOBALES =====================
let BASE_PATH = ""; // Ruta base para datos e imágenes

// ===================== CARGA INICIAL =====================
window.onload = async () => {
    console.log("%c Visor Médico DICOM V4.1 ", "background: #222; color: #bada55; font-size: 1.2rem;");
    initCornerstone();
    setupPan();
    setupWheel();
    setupKeyboard();

    // 🔍 DETECCIÓN ROBUSTA DE ID
    const urlParams = new URLSearchParams(window.location.search);
    let estudioId = urlParams.get('id');

    // Fallback: buscar en el hash (#id=3) por si acaso el router lo movió
    if (!estudioId && window.location.hash.includes('id=')) {
        estudioId = window.location.hash.split('id=')[1].split('&')[0];
    }

    if (estudioId) {
        // En XAMPP/Production: ../temp_disco_X/data/
        BASE_PATH = `../temp_disco_${estudioId}/`;
        console.log("✅ ID Detectado:", estudioId, "Ruta Base:", BASE_PATH);
    } else {
        BASE_PATH = ""; // Modo local (CD)
        console.warn("⚠️ No se detectó ID de estudio. Intentando modo local (CD).");
        console.log("URL Actual:", window.location.href);
    }

    try {
        const fetchUrl = (BASE_PATH || '') + 'data/paciente.json';
        const jsUrl = (BASE_PATH || '') + 'data/paciente.js';

        console.log("📡 Modo de carga detectado:", window.location.protocol);

        let data = null;

        // Función robusta para cargar vía Script (Inyección en DOM)
        const cargarViaScript = () => {
            return new Promise((resolve, reject) => {
                console.log("💿 Intentando cargar script:", jsUrl);
                const script = document.createElement('script');
                script.src = jsUrl;
                script.onload = () => {
                    if (window.ESTUDIO_DATA) {
                        console.log("✅ Datos cargados vía Script");
                        resolve(window.ESTUDIO_DATA);
                    } else {
                        reject(new Error("Variable ESTUDIO_DATA no definida en paciente.js"));
                    }
                };
                script.onerror = () => {
                    reject(new Error(`Fallo al cargar script: ${jsUrl}. Verifique que el archivo existe en el CD.`));
                };
                document.head.appendChild(script);
            });
        };

        // PRIORIDAD: Si estamos en disco local (file:), usar script SIEMPRE
        if (window.location.protocol === 'file:' || window.location.hostname === "") {
            data = await cargarViaScript();
        } else {
            // En servidor web (XAMPP/Producción), intentamos fetch primero
            try {
                console.log("🌐 Intentando fetch:", fetchUrl);
                const response = await fetch(fetchUrl + `?v=${new Date().getTime()}`);
                if (response.ok) {
                    data = await response.json();
                } else {
                    console.warn("⚠️ Fetch falló con estado:", response.status);
                    data = await cargarViaScript();
                }
            } catch (fetchErr) {
                console.warn("⚠️ Error de red/CORS en fetch. Usando fallback de script...");
                data = await cargarViaScript();
            }
        }

        if (!data) throw new Error("No se pudo cargar la información del estudio por ningún método.");

        // 👤 Mostrar nombre del paciente limpiando separadores DICOM (^ y espacios dobles)
        let nombreRaw = data.paciente || 'PACIENTE DESCONOCIDO';
        let nombreLimpio = nombreRaw.replace(/\^/g, ' ').replace(/\s+/g, ' ').trim();
        document.getElementById('nombre-paciente').textContent = nombreLimpio.toUpperCase();

        document.getElementById('id-paciente').textContent = data.paciente_id ? `[ID: ${data.paciente_id}]` : '';
        document.getElementById('modalidad-estudio').textContent = data.modalidad || '—';
        document.getElementById('descripcion-estudio').textContent = data.descripcion || '';
        document.getElementById('fecha-estudio').textContent = data.fecha || '—';

        if (data.study_uid) {
            document.getElementById('uid-container').style.display = 'inline';
            document.getElementById('uid-estudio').textContent = data.study_uid;
        }

        // 🧹 FILTRADO INTELIGENTE: Si hay BMP, ocultamos el DCM redundante
        const todas = data.imagenes || [];
        imagenes = todas.filter(img => {
            const low = img.toLowerCase();
            // Ignorar archivos de sistema y metadatos
            if (['json', 'dir', 'ini', 'db', 'txt'].some(ext => low.endsWith('.' + ext))) return false;

            if (low.endsWith('.dcm')) {
                // Si existe una versión con imagen para este mismo DICOM, preferimos la imagen
                const base = img.substring(0, img.lastIndexOf('.'));
                const hasRedundantImage = todas.some(f => {
                    const fLow = f.toLowerCase();
                    return f.startsWith(base) && (fLow.endsWith('.bmp') || fLow.endsWith('.jpg') || fLow.endsWith('.png'));
                });
                if (hasRedundantImage) return false;
            }
            return true;
        });

        actualizarContador();
        cargarMiniaturas();

        if (imagenes.length > 0) {
            cambiarImagen(0);
            setStatus(`Estudio cargado: ${imagenes.length} imagen(es) únicas.`);
        } else {
            document.getElementById('no-image-msg').style.display = 'flex';
            document.getElementById('imagen-actual').style.display = 'none';
            setStatus('No se encontraron imágenes en el estudio.');
        }
    } catch (e) {
        console.error('❌ Error crítico en visor:', e);
        document.getElementById('nombre-paciente').textContent = 'ERROR DE CARGA';
        document.getElementById('no-image-msg').style.display = 'flex';

        const protocolo = window.location.protocol;
        const msgError = `Error: ${e.message} (Protocolo: ${protocolo}). Verifique que la carpeta 'data' contenga los archivos del estudio.`;
        setStatus(msgError);
    }
};

function navegarImagen(delta) {
    if (imagenes.length === 0) return;
    let nuevo = indiceActual + delta;
    if (nuevo < 0) nuevo = imagenes.length - 1;
    if (nuevo >= imagenes.length) nuevo = 0;
    cambiarImagen(nuevo);
}

function fitToScreen() {
    currentZoom = 1;
    offsetX = 0;
    offsetY = 0;
    currentRotation = 0;
    aplicarTransformaciones();
    updateZoomIndicator();
}

function actualizarContador() {
    const el = document.getElementById('img-numero');
    const tot = document.getElementById('img-total');
    if (el) el.textContent = imagenes.length > 0 ? indiceActual + 1 : 0;
    if (tot) tot.textContent = imagenes.length;

    // Flechas de navegación
    const prev = document.getElementById('btn-prev');
    const next = document.getElementById('btn-next');
    if (prev) prev.style.display = imagenes.length > 1 ? 'flex' : 'none';
    if (next) next.style.display = imagenes.length > 1 ? 'flex' : 'none';
}

// ===================== MINIATURAS =====================
function cargarMiniaturas() {
    const lista = document.getElementById('lista-imagenes');
    // Mantener el título
    const title = lista.querySelector('.miniaturas-title');
    lista.innerHTML = '';
    if (title) lista.appendChild(title);
    else {
        const t = document.createElement('div');
        t.className = 'miniaturas-title';
        t.textContent = '📷 Imágenes';
        lista.appendChild(t);
    }

    imagenes.forEach((img, index) => {
        const div = document.createElement('div');
        div.className = 'miniatura';
        div.title = img;

        const isDcm = img.toLowerCase().endsWith('.dcm') || !img.includes('.');
        if (isDcm) {
            div.innerHTML = '<span class="dcm-label">DICOM</span><span class="dcm-num">' + (index + 1) + '</span>';
        } else {
            const safePath = img.split('/').map(p => encodeURIComponent(p)).join('/');
            div.style.backgroundImage = `url('${BASE_PATH}data/${safePath}')`;
            const numSpan = document.createElement('span');
            numSpan.className = 'mini-num';
            numSpan.textContent = index + 1;
            div.appendChild(numSpan);
        }

        div.onclick = () => cambiarImagen(index);
        lista.appendChild(div);
    });
}

// ===================== CAMBIAR IMAGEN =====================
async function cambiarImagen(index) {
    if (index < 0 || index >= imagenes.length) return;

    indiceActual = index;
    const imgName = imagenes[index];
    const extension = imgName.includes('.') ? imgName.split('.').pop().toLowerCase() : '';

    esDicomActual = (extension === 'dcm' || extension === 'dicom' || extension === '');
    if (['bmp', 'jpg', 'jpeg', 'png', 'gif', 'dmp'].includes(extension)) {
        esDicomActual = false;
    }

    const imgElement = document.getElementById('imagen-actual');
    const dicomElement = document.getElementById('dicom-viewer');
    const noImgMsg = document.getElementById('no-image-msg');

    if (noImgMsg) noImgMsg.style.display = 'none';

    // Reiniciar posición
    offsetX = 0; offsetY = 0;
    currentRotation = 0;

    let cleanName = imgName;
    if (cleanName.startsWith('/')) cleanName = cleanName.substring(1);
    const safePath = cleanName.split('/').map(p => encodeURIComponent(p)).join('/');
    const finalUrl = `${BASE_PATH}data/${safePath}`;

    if (esDicomActual) {
        imgElement.style.display = 'none';
        dicomElement.style.display = 'block';
        const imageId = 'wadouri:' + finalUrl;

        try {
            const image = await cornerstone.loadImage(imageId);
            cornerstone.displayImage(dicomElement, image);
            fitToScreen(); // Auto-zoom
            setStatus('Radiografía: ' + imgName);
        } catch (err) {
            console.error('Error DICOM:', err);
            dicomElement.innerHTML = `<div style="color:white; text-align:center; margin-top:20%"><p>⚠️ Error DICOM</p></div>`;
        }
    } else {
        dicomElement.style.display = 'none';
        imgElement.style.display = 'block';
        imgElement.src = finalUrl;

        imgElement.onload = () => {
            console.log("✅ Imagen cargada:", imgElement.naturalWidth, "x", imgElement.naturalHeight);
            fitToScreen();
            setStatus('Imagen: ' + imgName);
        };
        imgElement.onerror = () => {
            console.error('❌ Fallo al cargar:', finalUrl);
            setStatus('Error: ' + imgName);
        };
    }

    // UI
    document.querySelectorAll('.miniatura').forEach((m, i) => m.classList.toggle('activa', i === index));
    const minis = document.querySelectorAll('.miniatura');
    if (minis[index]) minis[index].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
    actualizarContador();
}

// ===================== TRANSFORMACIONES =====================
function zoom(factor) {
    currentZoom = Math.max(0.1, Math.min(currentZoom * factor, 15));
    aplicarTransformaciones();
    updateZoomIndicator();
}

function fitToScreen() {
    const contenedor = document.getElementById('contenedor-imagen');
    const containerW = contenedor.clientWidth * 0.95;
    const containerH = contenedor.clientHeight * 0.95;

    if (esDicomActual) {
        const element = document.getElementById('dicom-viewer');
        try {
            const viewport = cornerstone.getViewport(element);
            const image = cornerstone.getImage(element);
            if (viewport && image) {
                const scaleW = containerW / image.width;
                const scaleH = containerH / image.height;
                currentZoom = Math.min(scaleW, scaleH);
                viewport.scale = currentZoom;
                viewport.translation = { x: 0, y: 0 };
                cornerstone.setViewport(element, viewport);
            }
        } catch (e) { }
    } else {
        const img = document.getElementById('imagen-actual');
        if (img.naturalWidth > 0) {
            const scaleW = containerW / img.naturalWidth;
            const scaleH = containerH / img.naturalHeight;
            currentZoom = Math.min(scaleW, scaleH);
        } else {
            currentZoom = 1;
        }
    }

    offsetX = 0; offsetY = 0;
    aplicarTransformaciones();
    updateZoomIndicator();
}

function rotar(grados) {
    currentRotation = (currentRotation + grados) % 360;
    aplicarTransformaciones();
}

function ajustar(tipo) {
    if (tipo === 'brightness') {
        currentBrightness = currentBrightness > 225 ? 50 : currentBrightness + 25;
    } else if (tipo === 'contrast') {
        currentContrast = currentContrast > 225 ? 50 : currentContrast + 25;
    } else if (tipo === 'invert') {
        currentInvert = currentInvert === 0 ? 100 : 0;
        const btn = document.getElementById('btn-invertir');
        if (btn) btn.classList.toggle('active', currentInvert === 100);
    }
    aplicarTransformaciones();
}

function reset() {
    currentBrightness = 100;
    currentContrast = 100;
    currentInvert = 0;
    const btn = document.getElementById('btn-invertir');
    if (btn) btn.classList.remove('active');
    fitToScreen();
}

function aplicarTransformaciones() {
    const filterStr = `brightness(${currentBrightness}%) contrast(${currentContrast}%) invert(${currentInvert}%)`;

    if (esDicomActual) {
        const element = document.getElementById('dicom-viewer');
        try {
            const viewport = cornerstone.getViewport(element);
            if (viewport) {
                viewport.scale = currentZoom;
                viewport.rotation = currentRotation;
                viewport.translation = { x: offsetX, y: offsetY };
                cornerstone.setViewport(element, viewport);
            }
            element.style.filter = filterStr;
        } catch (e) { /* cornerstone no inicializado aún */ }
    } else {
        const img = document.getElementById('imagen-actual');
        img.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${currentZoom}) rotate(${currentRotation}deg)`;
        img.style.filter = filterStr;
    }
}

function updateZoomIndicator() {
    const el = document.getElementById('zoom-indicator');
    if (el) el.textContent = Math.round(currentZoom * 100) + '%';
}

// ===================== PAN (ARRASTRAR) =====================
function setupPan() {
    const contenedor = document.getElementById('contenedor-imagen');

    contenedor.addEventListener('mousedown', e => {
        if (e.button !== 0) return;
        isPanning = true;
        panStartX = e.clientX - offsetX;
        panStartY = e.clientY - offsetY;
        contenedor.style.cursor = 'grabbing';
    });

    document.addEventListener('mousemove', e => {
        if (!isPanning) return;
        offsetX = e.clientX - panStartX;
        offsetY = e.clientY - panStartY;
        aplicarTransformaciones();
    });

    document.addEventListener('mouseup', () => {
        isPanning = false;
        const contenedor = document.getElementById('contenedor-imagen');
        if (contenedor) contenedor.style.cursor = 'grab';
    });

    // Touch (móvil)
    if (typeof Hammer !== 'undefined') {
        const hammer = new Hammer(contenedor);
        hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
        hammer.on('pan', e => {
            offsetX = e.deltaX;
            offsetY = e.deltaY;
            aplicarTransformaciones();
        });
        hammer.get('pinch').set({ enable: true });
        hammer.on('pinchin', () => zoom(0.92));
        hammer.on('pinchout', () => zoom(1.08));
    }
}

// ===================== RUEDA DEL MOUSE (ZOOM) =====================
function setupWheel() {
    const contenedor = document.getElementById('contenedor-imagen');
    contenedor.addEventListener('wheel', e => {
        e.preventDefault();
        const factor = e.deltaY < 0 ? 1.1 : 0.9;
        zoom(factor);
    }, { passive: false });
}

// ===================== TECLADO =====================
function setupKeyboard() {
    document.addEventListener('keydown', e => {
        // No activar si el foco está en un input
        if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;

        switch (e.key) {
            case 'ArrowRight': case 'ArrowDown': navegarImagen(1); break;
            case 'ArrowLeft': case 'ArrowUp': navegarImagen(-1); break;
            case '+': case '=': zoom(1.15); break;
            case '-': case '_': zoom(0.87); break;
            case 'r': case 'R': reset(); break;
            case 'f': case 'F': fitToScreen(); break;
            case 'i': case 'I': ajustar('invert'); break;
            case 'b': case 'B': ajustar('brightness'); break;
            case 'c': case 'C': ajustar('contrast'); break;
            case 'Home': cambiarImagen(0); break;
            case 'End': cambiarImagen(imagenes.length - 1); break;
        }
    });
}

// ===================== STATUS BAR =====================
function setStatus(msg) {
    const el = document.getElementById('status-bar');
    if (el) el.textContent = msg;
}
