/**
 * DASHBOARD DEPARTAMENTO DE AUSCULTACIÓN - KELLER
 * Lógica de Three.js, GSAP y Sistema de Partículas
 */

// --- CONFIGURACIÓN DE DATOS DE NOTEBOOKS ---
const notebooksData = [
    {
        title: "DTL",
        subtitle: "PDA & ALLWAVE Analysis",
        description: "Dynamic Load Testing (DLT) y Pile Driving Analysis (PDA) utilizan teoría de ondas de esfuerzo unidimensional para evaluar capacidad e integridad de cimentaciones.",
        sources: 11,
        icon: "📊",
        colorClass: "cyan",
        url: "https://notebooklm.google.com/notebook/97733b4a-ed4d-4cad-add8-f6b07aa98980"
    },
    {
        title: "Hidroniveles",
        subtitle: "Monitoreo Estructural",
        description: "Gestión de nivel de agua mediante sensores automatizados, células hidrostáticas y relés conductivos avanzados para monitoreo industrial preciso.",
        sources: 28,
        icon: "💧",
        colorClass: "magenta",
        url: "https://notebooklm.google.com/notebook/f061fb2f-96e3-414b-8d34-7e2fda4c3d41"
    },
    {
        title: "Sismógrafo",
        subtitle: "Monitoreo de Vibraciones",
        description: "Sistema profesional Omnidots SWARM para monitoreo de vibraciones ambientales y estructurales en entornos de construcción.",
        sources: 1,
        icon: "📡",
        colorClass: "lime",
        url: "https://notebooklm.google.com/notebook/c8a96353-8e8a-44cf-b9ee-aecd647d4ff9"
    },
    {
        title: "PET",
        subtitle: "Integridad de Pilotes",
        description: "Evaluación de integridad por impacto de baja deformación (Pulse Echo). Análisis de velocidad y fuerza para evaluar continuidad de pilotes.",
        sources: 1,
        icon: "🔬",
        colorClass: "blue",
        url: "https://notebooklm.google.com/notebook/488e4729-b837-4d25-b900-53822c4525aa"
    },
    {
        title: "PDC & PDA",
        subtitle: "Geotecnia Aplicada",
        description: "Cimentaciones profundas mediante pilotes hincados. Normas técnicas regulan diseño, ensayos e impactos ambientales en obra.",
        sources: 8,
        icon: "🏗️",
        colorClass: "pink",
        url: "https://notebooklm.google.com/notebook/7bb768b2-a9f7-4ad7-a6d6-e64105a8bf67"
    },
    {
        title: "TILTS",
        subtitle: "Inclinómetros",
        description: "Monitoreo de verticalidad y deformación en estructuras mediante sensores de inclinación de alta precisión.",
        sources: 5,
        icon: "📐",
        colorClass: "orange",
        url: "https://notebooklm.google.com/"
    }
];

// --- CONTROL DE ANIMACIONES GLOBAL ---
let isDashboardPaused = false;
let threeAnimationFrameId = null;
let chartAnimationFrameId = null;
let terminalIntervalId = null;

// --- SISTEMA DE PARTÍCULAS EN CANVAS ---
const initParticles = () => {
    const canvas = document.getElementById('particles-canvas');
    if (!canvas) return;
    const ctx = canvas.getContext('2d');

    const particles = [];
    const particleCount = 50;

    const resize = () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    };
    window.addEventListener('resize', resize);
    resize();

    class Particle {
        constructor() {
            this.x = Math.random() * canvas.width;
            this.y = Math.random() * canvas.height;
            this.vx = (Math.random() - 0.5) * 0.5;
            this.vy = (Math.random() - 0.5) * 0.5;
            this.size = Math.random() * 2;
            this.alpha = Math.random() * 0.5;
        }

        update() {
            this.x += this.vx;
            this.y += this.vy;
            if (this.x < 0) this.x = canvas.width;
            if (this.x > canvas.width) this.x = 0;
            if (this.y < 0) this.y = canvas.height;
            if (this.y > canvas.height) this.y = 0;
        }

        draw() {
            ctx.fillStyle = `rgba(0, 255, 245, ${this.alpha})`;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            ctx.fill();
        }
    }

    for (let i = 0; i < particleCount; i++) particles.push(new Particle());

    const animateParticles = () => {
        if (!isDashboardPaused) {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            particles.forEach(p => {
                p.update();
                p.draw();
            });
            requestAnimationFrame(animateParticles);
        }
    };
    animateParticles();
};

// --- RENDER CARDS ---
const renderCards = () => {
    const grid = document.getElementById('notebooks-grid');
    if (!grid) return;
    grid.innerHTML = '';

    notebooksData.forEach((nb) => {
        const card = document.createElement('a');
        card.href = nb.url;
        card.className = `notebook-card ${nb.colorClass}`;
        card.target = "_blank";

        card.innerHTML = `
            <div class="card-icon">${nb.icon}</div>
            <div class="card-content">
                <h3 class="card-title">${nb.title}</h3>
                <div class="card-subtitle">${nb.subtitle}</div>
                <p class="card-desc">${nb.description}</p>
                <div class="card-footer">
                    <span class="source-count">${nb.sources} Fuentes</span>
                    <span class="arrow">→</span>
                </div>
            </div>
            <div class="card-glow"></div>
        `;

        // Listener manual para asegurar navegación (Force Open)
        card.addEventListener('click', (e) => {
            // Prevenir comportamiento default del <a> para manejarlo totalmente por JS
            e.preventDefault();
            console.log(`🚀 Click detectado en: ${nb.title}`);

            if (nb.url && nb.url.startsWith('http')) {
                const newWindow = window.open(nb.url, '_blank');
                if (!newWindow) {
                    alert("⚠️ El navegador bloqueó la ventana emergente. Por favor permite pop-ups para este sitio.");
                }
            } else {
                alert("🚫 Enlace no configurado: " + nb.url);
            }
        });

        grid.appendChild(card);
    });
};

// --- WISEN DATA (Eliminado en reversión) ---
// La funcionalidad de datos reales se ha revertido para estabilidad.

// --- THREE.JS: MODELO 3D INTERACTIVO ---
const initThreeJS = () => {
    const canvas = document.getElementById('model-canvas');
    if (!canvas) return;

    // Ajustar tamaño inicial al contenedor
    const container = canvas.parentElement;

    const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });
    renderer.setClearColor(0x000000, 0);
    renderer.setSize(container.clientWidth, container.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);

    const scene = new THREE.Scene();

    const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 1000);
    camera.position.set(12, 10, 15);

    const controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.autoRotate = true;
    controls.autoRotateSpeed = 1.0;
    controls.target.set(0, 2, 0);

    // Luces
    const ambientLight = new THREE.AmbientLight(0xffffff, 1.2);
    scene.add(ambientLight);

    const dirLight = new THREE.DirectionalLight(0xffffff, 1.5);
    dirLight.position.set(15, 20, 10);
    scene.add(dirLight);

    const fillLight = new THREE.DirectionalLight(0x003e7e, 0.8);
    fillLight.position.set(-10, 10, -10);
    scene.add(fillLight);

    // Loader
    const loader = new THREE.GLTFLoader();
    loader.load('assets/junttan.glb', (gltf) => {
        const model = gltf.scene;
        model.scale.set(0.6, 0.6, 0.6);
        model.position.y = -1;

        scene.add(model);
        console.log("Modelo Junttan cargado correctamente");
    }, undefined, (error) => {
        console.error('Error cargando modelo 3D:', error);
    });

    const resizeRenderer = () => {
        const width = container.clientWidth;
        const height = container.clientHeight;
        if (canvas.width !== width || canvas.height !== height) {
            renderer.setSize(width, height, false);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        }
    };
    window.addEventListener('resize', resizeRenderer);

    const animate = () => {
        if (!isDashboardPaused) {
            controls.update();
            renderer.render(scene, camera);
            threeAnimationFrameId = requestAnimationFrame(animate);
        }
    };
    animate();

    window.resumeThreeJS = () => {
        if (!threeAnimationFrameId) animate();
    };
};

// --- GSAP ANIMATIONS ---
const initAnimations = () => {
    if (typeof gsap === 'undefined') return;
    gsap.registerPlugin(ScrollTrigger);

    // Animación de entrada Header
    gsap.from('.header-content', {
        duration: 1.2, y: -30, opacity: 0, ease: 'power3.out'
    });

    // Animación Hero
    gsap.from('.hero-content', {
        duration: 1, x: -50, opacity: 0, delay: 0.3, ease: 'power3.out'
    });
    gsap.from('.hero-model', {
        duration: 1.2, x: 50, opacity: 0, delay: 0.3, ease: 'power3.out'
    });

    // Control Panel Stagger
    gsap.from('.control-card', {
        scrollTrigger: {
            trigger: '.control-panel-section',
            start: 'top 80%'
        },
        duration: 0.8,
        y: 40,
        opacity: 0,
        stagger: 0.15,
        ease: 'back.out(1.2)'
    });

    // Notebooks: Visibilidad inmediata asegurada
    gsap.set('.notebook-card', { opacity: 1, y: 0 });
};

// --- PANEL DE CONTROL: TERMINAL Y CHART ---
const initControlPanel = () => {
    // 1. Terminal
    const terminalContent = document.getElementById('terminal-content');
    if (terminalContent) {
        const messages = [
            "Conectando a Wisen Platform...",
            "Sincronizando sensores...",
            "Verificando integridad...",
            "ESTADO: NOMINAL",
            "Recibiendo paquete #4921",
            "Análisis espectral completado"
        ];

        const addMessage = () => {
            if (isDashboardPaused) return;
            const msg = messages[Math.floor(Math.random() * messages.length)];
            const line = document.createElement('div');
            line.className = 'terminal-line';
            line.innerHTML = `<span class="cmd">></span> ${msg}`;
            terminalContent.appendChild(line);

            // Auto scroll
            terminalContent.scrollTop = terminalContent.scrollHeight;

            if (terminalContent.children.length > 8) terminalContent.removeChild(terminalContent.firstChild);
        };
        terminalIntervalId = setInterval(addMessage, 3000);
    }

    // 2. Gráfico Wisen – Edificio
    if (typeof Chart !== 'undefined') {
        const CELL_COLORS = [
            '#00fff5', '#ff00ff', '#a0ff00', '#ffaa00',
            '#ff4444', '#4499ff', '#ff88cc', '#44ffaa', '#eeeeee',
            '#ffcc00', '#00ccff', '#cc00ff', '#00ffcc', '#ccff00'
        ];
        const CHART_HISTORY = 360; // 6 hours at 1 point/min

        const createWisenChart = (canvasId, legendId, updateId, fileName, nodeNames) => {
            const ctx = document.getElementById(canvasId);
            if (!ctx) return null;

            const chart = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: [],
                    datasets: nodeNames.map((name, i) => ({
                        label: name,
                        data: [],
                        borderColor: CELL_COLORS[i % CELL_COLORS.length],
                        backgroundColor: CELL_COLORS[i % CELL_COLORS.length] + '22',
                        borderWidth: 2,
                        pointRadius: 0,
                        tension: 0.3,
                        spanGaps: true
                    }))
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    animation: false,
                    plugins: { legend: { display: false } },
                    scales: {
                        x: {
                            type: 'category',
                            grid: { color: 'rgba(255,255,255,0.05)' },
                            ticks: {
                                color: 'rgba(255,255,255,0.3)',
                                font: { size: 9 },
                                maxRotation: 0,
                                callback: function (val, index) {
                                    return index % 30 === 0 ? this.getLabelForValue(val) : '';
                                }
                            }
                        },
                        y: {
                            title: { display: true, text: 'mm de asiento', color: 'rgba(255,255,255,0.5)', font: { size: 10 } },
                            grid: { color: 'rgba(255,255,255,0.05)' },
                            ticks: { color: 'rgba(255,255,255,0.5)', font: { size: 9 } }
                        }
                    }
                }
            });

            const legendEl = document.getElementById(legendId);
            if (legendEl) {
                legendEl.innerHTML = nodeNames.map((name, i) =>
                    `<span style="display:inline-flex;align-items:center;margin:2px 6px;font-size:10px;color:${CELL_COLORS[i % CELL_COLORS.length]}">
                        <svg width="14" height="4" style="margin-right:4px"><rect width="14" height="2" y="1" fill="${CELL_COLORS[i % CELL_COLORS.length]}"/></svg>
                        ${name}
                    </span>`
                ).join('');
            }

            let lastTs = null;
            const update = async () => {
                try {
                    const r = await fetch(`${fileName}?t=${Date.now()}`);
                    if (!r.ok) return;
                    const data = await r.json();
                    if (!Array.isArray(data) || data.length === 0) return;

                    const latest = data[data.length - 1];
                    if (latest.time === lastTs) return;
                    lastTs = latest.time;

                    const updateEl = document.getElementById(updateId);
                    if (updateEl) {
                        const d = new Date(latest.time);
                        updateEl.innerText = `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
                    }

                    const view = data.slice(-CHART_HISTORY);
                    chart.data.labels = view.map(p => {
                        const d = new Date(p.time);
                        return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
                    });
                    for (let i = 0; i < nodeNames.length; i++) {
                        chart.data.datasets[i].data = view.map(p =>
                            (p.cells && p.cells[i] !== undefined) ? p.cells[i] : null
                        );
                    }
                    chart.update('none');
                } catch (e) { console.error(`Error updating ${name}:`, e); }
            };

            update();
            setInterval(update, 30000);
            return chart;
        };

        // Initialize Pernet Chart
        createWisenChart(
            'wisen-pernet-chart',
            'wisen-pernet-legend',
            'wisen-pernet-update',
            'pernet_data.json',
            ['VE9B0101', 'VE9B0103', 'VE9B0104', 'VE9B0107', 'VE9B010F', 'VE9B0118', 'VE9B011D', 'VE9B0129', 'VE9B0153', 'VE9B0165']
        );

        // Initialize Cartagena Chart
        createWisenChart(
            'wisen-cartagena-chart',
            'wisen-cartagena-legend',
            'wisen-cartagena-update',
            'cartagena_data.json',
            ['19A01E9D', 'VE9D010C', 'VE9D0115', 'VE9D0116', 'VE9D0119', 'VE9D0129', 'VE9D0133', 'VE9D0194', 'VE9D01C2', 'VE9D01C8', 'VE9D01E7']
        );
    }
};

// --- VISOR 3D HIDRONIVELES (PANTALLA COMPLETA) ---
let hydroThreeInstance = null;

const initHydroViewer = () => {
    const trigger = document.getElementById('hydro-level-trigger');
    const overlay = document.getElementById('hydro-viewer-overlay');
    const closeBtn = document.getElementById('close-hydro-viewer');
    const container = document.getElementById('hydro-canvas-container');

    if (!trigger || !overlay || !closeBtn || !container) return;

    const openViewer = () => {
        overlay.classList.add('active');
        pauseDashboardAnimations();

        // Inicializar Three.js para el visor
        if (!hydroThreeInstance) {
            hydroThreeInstance = createHydroScene(container);
        } else {
            hydroThreeInstance.resume();
        }

        // Animación de entrada con GSAP
        gsap.to(overlay, { duration: 0.5, opacity: 1, ease: 'power2.out' });
    };

    const closeViewer = () => {
        gsap.to(overlay, {
            duration: 0.4,
            opacity: 0,
            ease: 'power2.in',
            onComplete: () => {
                overlay.classList.remove('active');
                if (hydroThreeInstance) hydroThreeInstance.pause();
                resumeDashboardAnimations();
            }
        });
    };

    trigger.addEventListener('click', openViewer);
    closeBtn.addEventListener('click', closeViewer);
};

const createHydroScene = (container) => {
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 5, 12);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    container.appendChild(renderer.domElement);

    const controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;

    // Luces
    const ambientLight = new THREE.AmbientLight(0xffffff, 2.0); // Aumentado drásticamente
    scene.add(ambientLight);

    const dirLight = new THREE.DirectionalLight(0xffffff, 2.5); // Luz principal muy fuerte
    dirLight.position.set(15, 20, 10);
    scene.add(dirLight);

    const fillLight = new THREE.DirectionalLight(0x00fff5, 1.5); // Relleno cian
    fillLight.position.set(-15, 10, -15);
    scene.add(fillLight);

    const backLight = new THREE.DirectionalLight(0xffffff, 1.0); // Contra luz
    backLight.position.set(0, 5, -20);
    scene.add(backLight);

    // CARGA DE MODELO REAL (hidronivel.glb)
    const loader = new THREE.GLTFLoader();
    const modelGroup = new THREE.Group();
    scene.add(modelGroup);

    loader.load('assets/hidronivel.glb', (gltf) => {
        const model = gltf.scene;

        // Auto-centrado y ajuste de escala
        const box = new THREE.Box3().setFromObject(model);
        const size = box.getSize(new THREE.Vector3());
        const center = box.getCenter(new THREE.Vector3());

        const maxDim = Math.max(size.x, size.y, size.z);
        const scale = 6 / maxDim; // Escala base para buena visibilidad
        model.scale.set(scale, scale, scale);

        model.position.x = -center.x * scale;
        model.position.y = -center.y * scale;
        model.position.z = -center.z * scale;

        modelGroup.add(model);
        console.log("✅ Modelo GLB de Hidronivel cargado correctamente");
    }, (xhr) => {
        // Opcional: Progresos de carga
    }, (error) => {
        console.error('❌ Error al cargar hidronivel.glb:', error);
    });

    let animationId = null;

    const animate = () => {
        animationId = requestAnimationFrame(animate);

        // Rotación suave del grupo
        if (modelGroup) {
            modelGroup.rotation.y += 0.005;
        }

        controls.update();
        renderer.render(scene, camera);
    };

    const onResize = () => {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    };

    window.addEventListener('resize', onResize);
    animate();

    return {
        pause: () => {
            if (animationId) cancelAnimationFrame(animationId);
            animationId = null;
        },
        resume: () => {
            if (!animationId) animate();
        }
    };
};

// --- API DE PAUSA GLOBAL ---
window.pauseDashboardAnimations = () => {
    isDashboardPaused = true;
    if (threeAnimationFrameId) {
        cancelAnimationFrame(threeAnimationFrameId);
        threeAnimationFrameId = null;
    }
    if (chartAnimationFrameId) {
        cancelAnimationFrame(chartAnimationFrameId);
        chartAnimationFrameId = null;
    }
    console.log("Dashboard animations PAUSED.");
};

window.resumeDashboardAnimations = () => {
    isDashboardPaused = false;
    if (window.resumeThreeJS) window.resumeThreeJS();
    if (window.resumeChart) window.resumeChart();
    console.log("Dashboard animations RESUMED.");
};

// --- WIDGETS DEL TIEMPO (OPEN-METEO) ---
const initWeather = () => {
    const locations = [
        { name: 'estepona', lat: 36.4271, lon: -5.1472, elementId: 'weather-estepona', windId: 'wind-estepona', rainId: 'rain-estepona' },
        { name: 'cartagena', lat: 37.6051, lon: -0.9867, elementId: 'weather-cartagena', windId: 'wind-cartagena', rainId: 'rain-cartagena' }
    ];

    const weatherCodes = {
        0: { icon: '☀️', desc: 'Despejado' },
        1: { icon: '🌤️', desc: 'Casi despejado' },
        2: { icon: '⛅', desc: 'Parcialmente nubes' },
        3: { icon: '☁️', desc: 'Cubierto' },
        45: { icon: '🌫️', desc: 'Niebla' },
        48: { icon: '🌫️', desc: 'Niebla escarcha' },
        51: { icon: '🌧️', desc: 'Llovizna suave' },
        53: { icon: '🌧️', desc: 'Llovizna' },
        55: { icon: '🌧️', desc: 'Llovizna intensa' },
        61: { icon: '🌧️', desc: 'Lluvia débil' },
        63: { icon: '🌧️', desc: 'Lluvia' },
        65: { icon: '🌧️', desc: 'Lluvia fuerte' },
        71: { icon: '❄️', desc: 'Nieve débil' },
        73: { icon: '❄️', desc: 'Nieve' },
        75: { icon: '❄️', desc: 'Nieve fuerte' },
        80: { icon: '🌦️', desc: 'Chubascos suaves' },
        81: { icon: '🌦️', desc: 'Chubascos' },
        82: { icon: '🌦️', desc: 'Chubascos violentos' },
        95: { icon: '⛈️', desc: 'Tormenta' }
    };

    locations.forEach(loc => {
        // Ejecutar fetch independiente sin bloquear el event loop con un forEach async
        (async () => {
            try {
                // URL con parámetros extendidos para viento y precipitación
                const url = `https://api.open-meteo.com/v1/forecast?latitude=${loc.lat}&longitude=${loc.lon}&current=temperature_2m,relative_humidity_2m,precipitation,weather_code,wind_speed_10m`;
                const response = await fetch(url);
                const data = await response.json();
                const current = data.current;

                const card = document.getElementById(loc.elementId);
                if (!card) return;

                const info = weatherCodes[current.weather_code] || { icon: '❓', desc: 'Desconocido' };

                // Actualización de campos
                card.querySelector('.weather-icon').innerText = info.icon;
                card.querySelector('.weather-temp').innerText = `${Math.round(current.temperature_2m)}°C`;
                card.querySelector('.weather-desc').innerText = info.desc;

                const windEl = document.getElementById(loc.windId);
                const rainEl = document.getElementById(loc.rainId);

                if (windEl) windEl.innerText = `${current.wind_speed_10m} km/h`;
                if (rainEl) rainEl.innerText = `${current.precipitation} mm`;

                console.log(`🌤️ Tiempo actualizado para ${loc.name}: ${current.temperature_2m}°C, Viento: ${current.wind_speed_10m}km/h`);
            } catch (error) {
                console.error(`Error al obtener el tiempo para ${loc.name}:`, error);
            }
        })();
    });
};

// --- INIT MAIN ---
const initDashboard = () => {
    console.log("🚀 Iniciando Dashboard Keller...");
    renderCards();
    initParticles();
    initControlPanel();
    // initWisenRealData(); // Revertido
    initThreeJS();
    initAnimations();
    initHydroViewer();
    initWeather();
};

document.addEventListener('DOMContentLoaded', initDashboard);
