"use client";

import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import { motion, AnimatePresence } from "framer-motion";
import Link from "next/link";
import Image from "next/image";
import Script from "next/script";
import { ArrowLeft, CheckCircle2, Zap, LayoutDashboard, Cpu, PencilRuler, Factory, MapPin, ChevronDown, Play, FileText, Box, Loader2, Maximize, X, ChevronLeft, ChevronRight } from "lucide-react";
import BreathingField from "@/components/visuals/BreathingField";
import AutoPlayVideo from "@/components/AutoPlayVideo";
import Breadcrumbs from "@/components/seo/Breadcrumbs";
import type { BreadcrumbItem } from "@/components/seo/Breadcrumbs";

// 🔥 EL TRUCO DEFINITIVO PARA TYPESCRIPT Y WEB COMPONENTS 🔥
// Al asignar el string a una variable con 'as any', TypeScript deja de 
// intentar validar las propiedades intrínsecas de JSX y compila sin chistar.
const ModelViewer = 'model-viewer' as any;

// ── LIGHTBOX CORREGIDO ──────────────────────────────────────────────────────
function ImageLightbox({ images, initialIndex, onClose }: {
  images: string[];
  initialIndex: number;
  onClose: () => void;
}) {
  const [currentIndex, setCurrentIndex] = useState(initialIndex);
  const touchStartX = useRef<number | null>(null);

  useEffect(() => {
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, []);

  const handleNext = (e?: React.MouseEvent | React.TouchEvent) => {
    e?.stopPropagation();
    setCurrentIndex((p) => (p + 1) % images.length);
  };
  const handlePrev = (e?: React.MouseEvent | React.TouchEvent) => {
    e?.stopPropagation();
    setCurrentIndex((p) => (p === 0 ? images.length - 1 : p - 1));
  };

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowRight') setCurrentIndex((p) => (p + 1) % images.length);
      if (e.key === 'ArrowLeft') setCurrentIndex((p) => (p === 0 ? images.length - 1 : p - 1));
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [images.length, onClose]);

  const onTouchStart = (e: React.TouchEvent) => {
    touchStartX.current = e.touches[0].clientX;
  };
  const onTouchEnd = (e: React.TouchEvent) => {
    if (touchStartX.current === null) return;
    const delta = e.changedTouches[0].clientX - touchStartX.current;
    if (Math.abs(delta) > 50) {
      delta < 0 ? handleNext() : handlePrev();
    }
    touchStartX.current = null;
  };

  const [mounted, setMounted] = useState(false);
  const portalElRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const el = document.createElement('div');
    el.id = 'lightbox-portal-' + Date.now();
    el.style.cssText = [
      'position:fixed',
      'inset:0',
      'z-index:99999',
      'pointer-events:auto',
      'touch-action:none',
      'isolation:isolate',
    ].join(';');
    document.documentElement.appendChild(el);
    portalElRef.current = el;
    setMounted(true);

    return () => {
      if (portalElRef.current && document.documentElement.contains(portalElRef.current)) {
        document.documentElement.removeChild(portalElRef.current);
        portalElRef.current = null;
      }
    };
  }, []);

  if (!mounted || !portalElRef.current) return null;

  return ReactDOM.createPortal(
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      transition={{ duration: 0.25 }}
      style={{
        position: 'fixed',
        inset: 0,
        zIndex: 99999,
        touchAction: 'none',
        WebkitOverflowScrolling: 'auto',
        overscrollBehavior: 'contain',
        display: 'flex',
        flexDirection: 'column',
        background: 'rgba(0,0,0,0.95)',
        backdropFilter: 'blur(20px)',
        WebkitBackdropFilter: 'blur(20px)',
      }}
      onClick={onClose}
      onTouchStart={onTouchStart}
      onTouchEnd={onTouchEnd}
    >
      <div className="flex items-center justify-between px-5 py-4 shrink-0" onClick={(e) => e.stopPropagation()}>
        <span className="text-white/50 font-mono text-sm tracking-widest">
          {images.length > 1 ? `${currentIndex + 1} / ${images.length}` : ''}
        </span>
        <button onClick={onClose} className="p-3 bg-white/10 hover:bg-white/20 active:bg-white/30 rounded-full text-white transition-colors touch-manipulation" style={{ minWidth: 44, minHeight: 44 }}>
          <X size={22} />
        </button>
      </div>

      <div className="flex-1 flex items-center justify-center px-4 md:px-20 relative min-h-0" onClick={(e) => e.stopPropagation()} style={{ touchAction: 'none' }}>
        <AnimatePresence mode="wait">
          <motion.img
            key={currentIndex}
            initial={{ opacity: 0, scale: 0.96 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 1.02 }}
            transition={{ duration: 0.3, ease: 'easeOut' }}
            src={images[currentIndex]}
            alt={`Imagen ${currentIndex + 1}`}
            style={{
              maxWidth: '100%',
              maxHeight: '100%',
              width: 'auto',
              height: 'auto',
              objectFit: 'contain',
              borderRadius: 12,
              boxShadow: '0 0 80px rgba(0,0,0,0.6)',
              display: 'block',
              background: 'rgba(255,255,255,0.03)',
            }}
          />
        </AnimatePresence>

        {images.length > 1 && (
          <>
            <button onClick={handlePrev} className="hidden md:flex absolute left-4 top-1/2 -translate-y-1/2 p-4 bg-white/10 hover:bg-white/20 rounded-full text-white transition-all hover:scale-110 backdrop-blur-md touch-manipulation"><ChevronLeft size={32} /></button>
            <button onClick={handleNext} className="hidden md:flex absolute right-4 top-1/2 -translate-y-1/2 p-4 bg-white/10 hover:bg-white/20 rounded-full text-white transition-all hover:scale-110 backdrop-blur-md touch-manipulation"><ChevronRight size={32} /></button>
          </>
        )}
      </div>

      {images.length > 1 && (
        <div className="flex md:hidden items-center justify-center gap-6 py-5 shrink-0" onClick={(e) => e.stopPropagation()}>
          <button onClick={handlePrev} className="p-4 bg-white/10 hover:bg-white/20 rounded-full text-white backdrop-blur-md touch-manipulation" style={{ minWidth: 52, minHeight: 52 }}><ChevronLeft size={26} /></button>
          <div className="flex gap-2">
            {images.map((_, i) => (
              <button key={i} onClick={(e) => { e.stopPropagation(); setCurrentIndex(i); }} className={`rounded-full transition-all touch-manipulation ${i === currentIndex ? 'w-5 h-2 bg-white' : 'w-2 h-2 bg-white/30'}`} />
            ))}
          </div>
          <button onClick={handleNext} className="p-4 bg-white/10 hover:bg-white/20 rounded-full text-white backdrop-blur-md touch-manipulation" style={{ minWidth: 52, minHeight: 52 }}><ChevronRight size={26} /></button>
        </div>
      )}
    </motion.div>,
    portalElRef.current
  );
}

// ── INLINE LIGHTWEIGHT 3D VIEWER ────────────────────────────────────────────
function InlineModelViewer({ glbPath, alt }: { glbPath: string; alt?: string }) {
  const [isActive, setIsActive] = useState(false);
  const [isLoaded, setIsLoaded] = useState(false);
  const viewerId = useRef(`imv-${Math.random().toString(36).slice(2)}`);

  const usdzPath = glbPath.replace(/\.glb$/i, '.usdz');

  useEffect(() => {
    if (!isActive) return;
    let attempts = 0;
    const tryRead = () => {
      const el = document.getElementById(viewerId.current) as any;
      if (!el) { if (++attempts < 20) setTimeout(tryRead, 300); return; }
      if ((el as any).modelIsVisible) { setIsLoaded(true); return; }
      el.addEventListener('load', () => setIsLoaded(true), { once: true });
    };
    const t = setTimeout(tryRead, 300);
    return () => clearTimeout(t);
  }, [isActive]);

  return (
    <div className="w-full my-8">
      <Script
        type="module"
        src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.5.0/model-viewer.min.js"
        strategy="afterInteractive"
      />

      {!isActive ? (
        <div
          className="relative rounded-2xl border border-[#0066CC]/20 dark:border-[#00F0FF]/20 overflow-hidden cursor-pointer group"
          onClick={() => setIsActive(true)}
          style={{ background: 'linear-gradient(135deg, #f0f4f8 0%, #e8edf4 100%)' }}
        >
          <div className="absolute inset-0 hidden dark:block" style={{ background: 'linear-gradient(135deg, #0a0a0c 0%, #0d1a2e 50%, #0a0a0c 100%)' }} />
          <div className="absolute inset-0 opacity-[0.04] dark:opacity-[0.08] pointer-events-none" style={{
            backgroundImage: 'linear-gradient(rgba(0,102,204,0.5) 1px,transparent 1px),linear-gradient(90deg,rgba(0,102,204,0.5) 1px,transparent 1px)',
            backgroundSize: '40px 40px',
          }} />

          <div className="relative z-10 p-6 md:p-8 flex flex-col sm:flex-row items-start sm:items-center gap-5">
            <div className="flex-1 min-w-0">
              <div className="inline-flex items-center gap-2 bg-[#0066CC]/10 dark:bg-[#0066CC]/20 border border-[#0066CC]/20 dark:border-[#0066CC]/30 rounded-full px-3 py-1 mb-3">
                <span className="w-1.5 h-1.5 rounded-full bg-[#0066CC] dark:bg-[#4DA6FF] animate-pulse" />
                <span className="text-[9px] font-bold uppercase tracking-[0.15em] text-[#0066CC] dark:text-[#4DA6FF]">3D Preview — AR Ready</span>
              </div>
              <h4 className="text-base md:text-lg font-medium text-[#1D1D1F] dark:text-white leading-tight">
                {alt || "Interactive 3D Model"}
              </h4>
              <div className="flex flex-wrap gap-1.5 mt-3">
                {['Drag to rotate', 'Pinch to zoom', 'AR on mobile'].map(cap => (
                  <span key={cap} className="text-[9px] text-[#86868B] dark:text-[#A1A1A6] bg-black/5 dark:bg-white/5 border border-black/5 dark:border-white/10 px-2 py-0.5 rounded-full">{cap}</span>
                ))}
              </div>
            </div>
            <button className="shrink-0 bg-[#0066CC] hover:bg-[#0055BB] text-white px-5 py-2.5 rounded-xl font-semibold text-sm transition-all shadow-md hover:shadow-lg flex items-center gap-2 group-hover:scale-[1.02] touch-manipulation">
              <Box size={16} /> Launch 3D
            </button>
          </div>
        </div>
      ) : (
        <motion.div
          initial={{ opacity: 0, scale: 0.98 }}
          animate={{ opacity: 1, scale: 1 }}
          style={{
            width: '100%',
            background: '#080c12',
            borderRadius: 16,
            border: '1px solid rgba(0,102,204,0.2)',
            boxShadow: '0 0 0 1px rgba(0,102,204,0.06), 0 12px 32px rgba(0,0,0,0.4)',
            position: 'relative',
            isolation: 'isolate',
          }}
        >
          <div style={{
            position: 'absolute', top: 10, left: 10, zIndex: 10, pointerEvents: 'none',
            display: 'inline-flex', alignItems: 'center', gap: 6,
            background: 'rgba(0,0,0,0.85)', border: `1px solid ${isLoaded ? 'rgba(74,222,128,0.3)' : 'rgba(59,130,246,0.3)'}`,
            borderRadius: 8, padding: '5px 10px',
          }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: isLoaded ? '#4ade80' : '#3b82f6', boxShadow: isLoaded ? '0 0 6px rgba(74,222,128,0.8)' : '0 0 6px rgba(59,130,246,0.8)' }} />
            <span style={{ fontSize: 9, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', fontFamily: 'monospace', color: isLoaded ? '#86efac' : 'rgba(255,255,255,0.5)' }}>
              {isLoaded ? 'Ready' : 'Loading...'}
            </span>
          </div>

          <button
            onClick={() => { setIsActive(false); setIsLoaded(false); }}
            style={{
              position: 'absolute', top: 10, right: 10, zIndex: 10,
              width: 32, height: 32, borderRadius: 8, border: '1px solid rgba(255,60,60,0.3)',
              background: 'rgba(0,0,0,0.85)', color: 'rgba(255,120,120,0.7)',
              cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
              WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation',
            }}
          >
            <X size={14} />
          </button>

          <ModelViewer
            id={viewerId.current}
            src={glbPath}
            ios-src={usdzPath}
            alt={alt || "3D Model"}
            ar
            ar-modes="quick-look scene-viewer webxr"
            ar-scale="auto"
            camera-controls
            auto-rotate
            auto-rotate-delay="800"
            rotation-per-second="14deg"
            shadow-intensity="1"
            exposure="1.1"
            environment-image="neutral"
            style={{
              display: 'block',
              width: '100%',
              height: '360px',
              background: 'transparent',
              borderRadius: 16,
              ['--poster-color' as any]: 'transparent',
              ['--progress-bar-color' as any]: '#3b82f6',
            }}
          >
            <button slot="ar-button" style={{
              position: 'absolute', bottom: 14, left: '50%', transform: 'translateX(-50%)',
              display: 'flex', alignItems: 'center', gap: 8,
              background: 'linear-gradient(135deg,#1d4ed8,#2563eb)', color: 'white',
              border: 'none', borderRadius: 32, padding: '10px 20px',
              fontWeight: 700, fontSize: 13, letterSpacing: '0.03em', cursor: 'pointer',
              boxShadow: '0 0 20px rgba(37,99,235,0.5),0 4px 16px rgba(0,0,0,0.4)',
              WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation', zIndex: 5,
            }}>
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
              </svg>
              View in AR
            </button>

            <div slot="poster" style={{
              position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
              alignItems: 'center', justifyContent: 'center', gap: 12, background: 'transparent',
            }}>
              <div style={{
                width: 36, height: 36, borderRadius: '50%', border: '3px solid rgba(59,130,246,0.15)',
                borderTop: '3px solid #3b82f6', animation: 'mv-spin 1s linear infinite',
              }} />
              <span style={{ color: '#6b7280', fontSize: 10, fontFamily: 'monospace', letterSpacing: '0.15em', textTransform: 'uppercase' }}>
                Loading...
              </span>
              <style>{`@keyframes mv-spin { to { transform: rotate(360deg); } }`}</style>
            </div>
          </ModelViewer>
        </motion.div>
      )}
    </div>
  );
}

// ── SUPER PARSER MARKDOWN MEJORADO v2 ───────────────────────────────────────
const renderMarkdown = (text: string, onImageClick: (url: string) => void) => {
  if (!text) return null;
  const lines = text.split('\n');
  
  // 🔥 CORRECCIÓN TYPESCRIPT: Usamos React.ReactNode en lugar de JSX.Element
  const elements: React.ReactNode[] = [];
  let listItems: React.ReactNode[] = [];
  let isOrderedList = false;

  let inTable = false;
  let tableHeaders: string[] = [];
  let tableRows: string[][] = [];

  const pushTable = () => {
    if (inTable) {
      elements.push(
        <div key={`table-${elements.length}`} className="my-8 w-full overflow-x-auto pb-4 [scrollbar-width:none]">
          <table className="w-full text-left border-collapse min-w-[600px] shadow-2xl rounded-2xl overflow-hidden border border-black/5 dark:border-white/5">
            <thead>
              <tr className="bg-[#1D1D1F] dark:bg-[#111]">
                {tableHeaders.map((th, i) => (
                  <th key={i} className={`p-4 border-b border-black/10 dark:border-white/10 text-[10px] md:text-xs uppercase tracking-widest font-semibold ${i === tableHeaders.length - 1 ? 'text-[#0066CC] dark:text-[#00F0FF] bg-[#0066CC]/5 dark:bg-[#00F0FF]/5' : 'text-white'}`}>
                    {parseInline(th)}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody className="bg-white/50 dark:bg-black/40 backdrop-blur-md">
              {tableRows.map((row, rIdx) => (
                <tr key={rIdx} className="hover:bg-black/5 dark:hover:bg-white/[0.02] transition-colors group">
                  {row.map((cell, cIdx) => (
                    <td key={cIdx} className={`p-4 border-b border-black/5 dark:border-white/5 text-xs md:text-sm ${cIdx === 0 ? 'text-[#86868B] font-medium' : cIdx === row.length - 1 ? 'text-[#1D1D1F] dark:text-white font-semibold bg-[#0066CC]/5 dark:bg-[#00F0FF]/5 group-hover:bg-[#0066CC]/10 dark:group-hover:bg-[#00F0FF]/10 transition-colors' : 'text-[#1D1D1F]/80 dark:text-white/80'}`}>
                      {parseInline(cell)}
                    </td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      );
      inTable = false;
      tableHeaders = [];
      tableRows = [];
    }
  };

  const pushList = () => {
    if (listItems.length > 0) {
      elements.push(
        isOrderedList ? (
          <ol key={`ol-${elements.length}`} className="list-decimal ml-5 mb-5 text-[#86868B] dark:text-[#A1A1A6] space-y-1.5 text-sm md:text-base font-light marker:text-[#0066CC] dark:marker:text-[#00F0FF]">
            {listItems}
          </ol>
        ) : (
          <ul key={`ul-${elements.length}`} className="list-disc ml-5 mb-5 text-[#86868B] dark:text-[#A1A1A6] space-y-1.5 text-sm md:text-base font-light marker:text-[#0066CC] dark:marker:text-[#00F0FF]">
            {listItems}
          </ul>
        )
      );
      listItems = [];
    }
  };

  const parseInline = (str: string) => {
    const boldRegex = /\*\*(.*?)\*\*/g;
    const italicRegex = /\*(.*?)\*/g;

    let parts = str.split(boldRegex);
    return parts.map((part, i) => {
      if (i % 2 === 1) return <strong key={i} className="font-semibold text-[#1D1D1F] dark:text-white">{part}</strong>;
      
      let subParts = part.split(italicRegex);
      return subParts.map((subPart, j) => {
        if (j % 2 === 1) return <em key={`${i}-${j}`} className="italic text-[#1D1D1F]/90 dark:text-white/90">{subPart}</em>;
        return subPart;
      });
    });
  };

  lines.forEach((line, idx) => {
    const trimmed = line.trim();

    if (!trimmed) {
      pushList(); pushTable();
      return;
    }

    if (trimmed.startsWith('|') && trimmed.endsWith('|')) {
      pushList();
      const cells = trimmed.split('|').filter((_, i, arr) => i !== 0 && i !== arr.length - 1).map(c => c.trim());
      
      if (!inTable) {
        inTable = true;
        tableHeaders = cells; 
      } else if (cells.every(c => c.match(/^[-:]+$/))) {
      } else {
        tableRows.push(cells); 
      }
      return;
    } else {
      pushTable(); 
    }

    const imgMatch = trimmed.match(/^!\[(.*?)\]\((.*?)\)$/);
    if (imgMatch) {
      pushList(); pushTable();
      const imageUrl = imgMatch[2];
      elements.push(
        <div 
          key={`img-${idx}`} 
          className="relative w-full my-8 rounded-2xl md:rounded-[2rem] overflow-hidden border border-black/10 dark:border-white/10 shadow-xl bg-[#F5F5F7] dark:bg-[#111] cursor-pointer group"
          onClick={() => onImageClick(imageUrl)}
        >
          <div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-all z-10 flex items-center justify-center opacity-0 group-hover:opacity-100 backdrop-blur-sm">
            <Maximize size={40} className="text-white drop-shadow-xl scale-90 group-hover:scale-100 transition-transform" />
          </div>
          <img src={imageUrl} alt={imgMatch[1]} className="w-full h-auto object-cover group-hover:scale-105 transition-transform duration-1000" loading="lazy" />
        </div>
      );
      return;
    }

    const videoMatch = trimmed.match(/^\[VIDEO:(.*?)\]$/);
    if (videoMatch) {
      pushList(); pushTable();
      const videoSrc = videoMatch[1].trim();
      const isLocalMp4 = videoSrc.endsWith('.mp4');
      elements.push(
        <div key={`vid-${idx}`} className="relative w-full my-8 rounded-2xl md:rounded-[2rem] overflow-hidden border border-black/10 dark:border-white/10 shadow-xl bg-black">
          <div className="absolute top-3 left-3 z-10 pointer-events-none">
            <div className="inline-flex items-center gap-1.5 bg-black/70 backdrop-blur-sm border border-white/10 rounded-full px-2.5 py-1">
              <Play size={10} className="text-white fill-white" />
              <span className="text-[9px] font-bold uppercase tracking-widest text-white/80 font-mono">Video</span>
            </div>
          </div>
          <div className="aspect-video">
            {isLocalMp4 ? (
              <AutoPlayVideo src={videoSrc} className="w-full h-full object-contain" />
            ) : (
              <iframe src={videoSrc} className="w-full h-full" allowFullScreen title="Embedded video" />
            )}
          </div>
        </div>
      );
      return;
    }

    const model3dMatch = trimmed.match(/^\[3D:(.*?)\]$/);
    if (model3dMatch) {
      pushList(); pushTable();
      const modelPath = model3dMatch[1].trim();
      elements.push(
        <InlineModelViewer key={`3d-${idx}`} glbPath={modelPath} alt="3D Technical Preview" />
      );
      return;
    }

    const h3Match = trimmed.match(/^###\s*(.*)/);
    if (h3Match) { 
      pushList(); 
      elements.push(<h3 key={idx} className="text-lg md:text-xl mt-6 mb-3 font-medium text-[#0066CC] dark:text-[#00F0FF]">{parseInline(h3Match[1])}</h3>); 
      return; 
    }

    const h2Match = trimmed.match(/^##\s*(.*)/);
    if (h2Match) { 
      pushList(); 
      elements.push(<h2 key={idx} className="text-2xl md:text-3xl mt-8 mb-4 font-light text-[#1D1D1F] dark:text-white tracking-tight">{parseInline(h2Match[1])}</h2>); 
      return; 
    }

    const h1Match = trimmed.match(/^#\s*(.*)/);
    if (h1Match) { 
      pushList(); 
      elements.push(<h1 key={idx} className="text-3xl md:text-4xl mt-10 mb-5 font-light text-[#1D1D1F] dark:text-white tracking-tight">{parseInline(h1Match[1])}</h1>); 
      return; 
    }

    const quoteMatch = trimmed.match(/^>\s*(.*)/);
    if (quoteMatch) {
      pushList();
      elements.push(<blockquote key={idx} className="border-l-4 border-[#0066CC] dark:border-[#00F0FF] pl-4 py-2 my-6 text-base md:text-lg font-light italic text-[#1D1D1F]/70 dark:text-[#A1A1A6] bg-[#0066CC]/5 dark:bg-[#00F0FF]/5 rounded-r-xl shadow-inner">{parseInline(quoteMatch[1])}</blockquote>);
      return;
    }

    const ulMatch = trimmed.match(/^[-*]\s+(.*)/);
    if (ulMatch) {
      isOrderedList = false;
      listItems.push(<li key={idx} className="leading-relaxed pl-1">{parseInline(ulMatch[1])}</li>);
      return;
    }

    const olMatch = trimmed.match(/^\d+\.\s*(.*)/);
    if (olMatch) {
      isOrderedList = true;
      listItems.push(<li key={idx} className="leading-relaxed pl-1">{parseInline(olMatch[1])}</li>);
      return;
    }

    if (trimmed === '---' || trimmed === '***' || trimmed === '___') {
      pushList();
      elements.push(<hr key={idx} className="my-8 border-0 h-px bg-gradient-to-r from-transparent via-black/10 dark:via-white/10 to-transparent" />);
      return;
    }

    pushList();
    elements.push(
      <p key={idx} className="text-[#86868B] dark:text-[#A1A1A6] font-light leading-relaxed mb-4 text-sm md:text-base">
        {parseInline(trimmed)}
      </p>
    );
  });

  pushList();
  pushTable(); 

  return <>{elements}</>;
};

// ── VISOR 3D TÉCNICO PROFESIONAL ─────────────────────────────────────────────
function TechnicalViewer3D({ node, usdzPath }: { node: any; usdzPath: string }) {
  const [isActive,   setIsActive]   = useState(false);
  const [isLoaded,   setIsLoaded]   = useState(false);
  const [autoRotate, setAutoRotate] = useState(true);
  const [showHuman,  setShowHuman]  = useState(true);
  const [showGrid,   setShowGrid]   = useState(true);
  const [modelDims,  setModelDims]  = useState<{ x: number; y: number; z: number } | null>(null);
  const viewerId = useRef(`mv-${node.id || Math.random().toString(36).slice(2)}`);

  useEffect(() => {
    if (!isActive) return;
    let attempts = 0;
    const tryRead = () => {
      const el = document.getElementById(viewerId.current) as any;
      if (!el) { if (++attempts < 20) setTimeout(tryRead, 200); return; }
      const read = () => {
        setIsLoaded(true);
        try {
          const bb = el.getBoundingBox?.();
          if (bb?.min && bb?.max) {
            setModelDims({
              x: parseFloat(Math.abs(bb.max.x - bb.min.x).toFixed(2)),
              y: parseFloat(Math.abs(bb.max.y - bb.min.y).toFixed(2)),
              z: parseFloat(Math.abs(bb.max.z - bb.min.z).toFixed(2)),
            });
          }
        } catch (_) {}
      };
      if ((el as any).modelIsVisible) { read(); return; }
      el.addEventListener('load', read, { once: true });
    };
    const t = setTimeout(tryRead, 300);
    return () => clearTimeout(t);
  }, [isActive]);

  const toggleRotate = () => {
    const el = document.getElementById(viewerId.current) as any;
    const next = !autoRotate;
    setAutoRotate(next);
    if (el) el.autoRotate = next;
  };

  let datasheetDims: { w?: string; h?: string; d?: string } = {};
  try {
    const dimsJson = JSON.parse(node.model3DDimsJson || '{}');
    if (dimsJson.w && dimsJson.h && dimsJson.d) {
      const factor = dimsJson.unit === 'm' ? 1000 : dimsJson.unit === 'cm' ? 10 : 1;
      datasheetDims = {
        w: String(Math.round(Number(dimsJson.w) * factor)),
        h: String(Math.round(Number(dimsJson.h) * factor)),
        d: String(Math.round(Number(dimsJson.d) * factor)),
      };
    } else {
      const ds = JSON.parse(node.specificDatasheetJson || '{}');
      (ds.specs || []).forEach((s: any) => {
        const lbl = (s.label || '').toLowerCase();
        if (lbl.includes('dimension') || lbl.includes('dim')) {
          const m = (s.value || '').match(/(\d+)\s*[xX×]\s*(\d+)\s*[xX×]\s*(\d+)/);
          if (m) datasheetDims = { w: m[1], h: m[2], d: m[3] };
        }
      });
    }
  } catch (_) {}

  const dims = modelDims
    ? { w: (modelDims.x * 1000).toFixed(0), h: (modelDims.y * 1000).toFixed(0), d: (modelDims.z * 1000).toFixed(0) }
    : datasheetDims;
  const hasDims = !!(dims.w && dims.h && dims.d);

  const VIEWER_HEIGHT_MOBILE = 420;
  const VIEWER_HEIGHT_DESKTOP = 580;

  return (
    <div className="w-full space-y-4">
      <Script
        type="module"
        src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.5.0/model-viewer.min.js"
        strategy="afterInteractive"
      />

      {!isActive && (
        <motion.div
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          className="relative rounded-[2rem] border border-[#0066CC]/20 shadow-2xl"
          style={{ background: 'linear-gradient(135deg, #0a0a0c 0%, #0d1a2e 50%, #0a0a0c 100%)', overflow: 'hidden' }}
        >
          <div className="absolute inset-0 opacity-10 pointer-events-none" style={{
            backgroundImage: 'linear-gradient(rgba(0,102,204,0.4) 1px,transparent 1px),linear-gradient(90deg,rgba(0,102,204,0.4) 1px,transparent 1px)',
            backgroundSize: '40px 40px',
          }} />
          <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,rgba(0,102,204,0.15)_0%,transparent_70%)] pointer-events-none" />

          <div className="relative z-10 p-8 md:p-12 flex flex-col md:flex-row items-start md:items-center gap-8">
            <div className="flex-1">
              <div className="inline-flex items-center gap-2 bg-[#0066CC]/20 border border-[#0066CC]/30 rounded-full px-4 py-1.5 mb-5">
                <span className="w-2 h-2 rounded-full bg-[#0066CC] animate-pulse" />
                <span className="text-[10px] font-bold uppercase tracking-[0.2em] text-[#4DA6FF]">Digital Twin — AR Ready</span>
              </div>
              <h4 className="text-2xl md:text-3xl font-light text-white mb-3 tracking-tight">
                {node.title}
                <span className="block text-base font-normal text-[#86868B] mt-1">Interactive 3D Technical Model</span>
              </h4>
              {hasDims && (
                <div className="flex flex-wrap gap-3 mt-5">
                  {[{label:'WIDTH',value:dims.w},{label:'HEIGHT',value:dims.h},{label:'DEPTH',value:dims.d}].map(d => (
                    <div key={d.label} className="bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-center">
                      <span className="block text-[9px] text-[#86868B] uppercase tracking-widest mb-0.5">{d.label}</span>
                      <span className="block text-white font-mono text-lg leading-none">{d.value}</span>
                      <span className="block text-[10px] text-[#4DA6FF]">mm</span>
                    </div>
                  ))}
                </div>
              )}
              <div className="flex flex-wrap gap-2 mt-5">
                {['Drag to rotate','Pinch to zoom','AR on mobile'].map(cap => (
                  <span key={cap} className="text-[10px] text-[#A1A1A6] bg-white/5 border border-white/10 px-3 py-1 rounded-full">{cap}</span>
                ))}
              </div>
            </div>
            <button onClick={() => setIsActive(true)} className="shrink-0 group relative bg-[#0066CC] hover:bg-[#0055BB] text-white px-8 py-4 rounded-2xl font-semibold text-sm transition-all shadow-[0_0_30px_rgba(0,102,204,0.4)] hover:shadow-[0_0_50px_rgba(0,102,204,0.6)] flex items-center gap-3 touch-manipulation">
              <Box size={20} /> Launch 3D Viewer
            </button>
          </div>
        </motion.div>
      )}

      {isActive && (
        <motion.div
          initial={{ opacity: 0, scale: 0.98 }}
          animate={{ opacity: 1, scale: 1 }}
          style={{ width: '100%', background: '#080c12', borderRadius: 20, border: '1px solid rgba(0,102,204,0.25)', boxShadow: '0 0 0 1px rgba(0,102,204,0.08), 0 20px 40px rgba(0,0,0,0.5)', position: 'relative', isolation: 'isolate' }}
        >
          {showGrid && (
            <div style={{ position: 'absolute', inset: 0, borderRadius: 20, opacity: 0.06, pointerEvents: 'none', zIndex: 1, backgroundImage: 'linear-gradient(rgba(0,102,204,0.8) 1px,transparent 1px),linear-gradient(90deg,rgba(0,102,204,0.8) 1px,transparent 1px)', backgroundSize: '50px 50px' }} />
          )}

          <div style={{ position: 'absolute', top: 12, left: 12, right: 12, zIndex: 10, pointerEvents: 'none', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6, boxSizing: 'border-box' }}>
            <div style={{ pointerEvents: 'auto', display: 'inline-flex', alignItems: 'center', gap: 7, background: 'rgba(0,0,0,0.9)', border: `1px solid ${isLoaded ? 'rgba(74,222,128,0.3)' : 'rgba(59,130,246,0.3)'}`, borderRadius: 10, padding: '7px 11px', flexShrink: 1, minWidth: 0 }}>
              <span style={{ width: 7, height: 7, borderRadius: '50%', flexShrink: 0, background: isLoaded ? '#4ade80' : '#3b82f6', boxShadow: isLoaded ? '0 0 6px rgba(74,222,128,0.8)' : '0 0 6px rgba(59,130,246,0.8)' }} />
              <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', fontFamily: 'monospace', color: isLoaded ? '#86efac' : 'rgba(255,255,255,0.5)', whiteSpace: 'nowrap', overflow: 'hidden' }}>{isLoaded ? 'Model Ready' : 'Loading...'}</span>
            </div>

            <div style={{ pointerEvents: 'auto', display: 'flex', alignItems: 'center', gap: 5, flexShrink: 0 }}>
              {[
                { active: autoRotate, onClick: toggleRotate, title: 'Rotation', icon: <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg> },
                { active: showHuman, onClick: () => setShowHuman(v => !v), title: 'Scale ref', icon: <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="5" r="2.2"/><path d="M12 8v7m-4-4 4 2 4-2M9 21l3-4 3 4"/></svg> },
                { active: showGrid, onClick: () => setShowGrid(v => !v), title: 'Grid', icon: <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/></svg> },
              ].map(btn => (
                <button key={btn.title} onClick={btn.onClick} title={btn.title} style={{ width: 38, height: 38, borderRadius: 10, flexShrink: 0, border: btn.active ? '1.5px solid rgba(59,130,246,0.7)' : '1.5px solid rgba(255,255,255,0.1)', background: btn.active ? 'rgba(59,130,246,0.22)' : 'rgba(0,0,0,0.88)', color: btn.active ? '#93c5fd' : 'rgba(255,255,255,0.45)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}>
                  {btn.icon}
                </button>
              ))}
              <button onClick={() => { setIsActive(false); setIsLoaded(false); setModelDims(null); }} title="Close" style={{ width: 38, height: 38, borderRadius: 10, flexShrink: 0, border: '1.5px solid rgba(255,60,60,0.3)', background: 'rgba(0,0,0,0.88)', color: 'rgba(255,120,120,0.7)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}>
                <X size={17} />
              </button>
            </div>
          </div>

          <ModelViewer
            id={viewerId.current}
           src={`/cases/${nodeToSlug(node.title)}/models/${node.model3DPath}`}
            ios-src={`/cases/${nodeToSlug(node.title)}/models/${usdzPath}`}
            alt={`3D Technical Model: ${node.title}`}
            ar
            ar-modes="quick-look scene-viewer webxr"
            ar-scale="fixed"
            camera-controls
            auto-rotate
            auto-rotate-delay="1000"
            rotation-per-second="12deg"
            shadow-intensity="1.5"
            shadow-softness="0.8"
            exposure="1.1"
            environment-image="neutral"
            style={{ display: 'block', width: '100%', height: `${VIEWER_HEIGHT_MOBILE}px`, background: 'transparent', borderRadius: 20, ['--poster-color' as any]: 'transparent', ['--progress-bar-color' as any]: '#3b82f6', ['--progress-mask' as any]: 'none' }}
          >
            {showHuman && (
              <div slot="hotspot-human" data-position="1.8 0 0" data-normal="0 1 0" style={{ pointerEvents: 'none' }}>
                <svg width="26" height="84" viewBox="0 0 26 84" fill="none" style={{ filter: 'drop-shadow(0 0 8px rgba(59,130,246,0.9))' }}>
                  <circle cx="13" cy="7" r="5.5" fill="rgba(59,130,246,0.9)" />
                  <rect x="9" y="13" width="8" height="26" rx="3" fill="rgba(59,130,246,0.9)" />
                  <rect x="1" y="15" width="8" height="18" rx="3" fill="rgba(59,130,246,0.6)" />
                  <rect x="17" y="15" width="8" height="18" rx="3" fill="rgba(59,130,246,0.6)" />
                  <rect x="7" y="39" width="6" height="26" rx="3" fill="rgba(59,130,246,0.9)" />
                  <rect x="13" y="39" width="6" height="26" rx="3" fill="rgba(59,130,246,0.9)" />
                  <text x="13" y="80" textAnchor="middle" fill="#93c5fd" fontSize="6.5" fontFamily="monospace" fontWeight="bold">1.75m</text>
                </svg>
              </div>
            )}

            <button slot="ar-button" style={{ position: 'absolute', bottom: 16, left: '50%', transform: 'translateX(-50%)', display: 'flex', alignItems: 'center', gap: 9, background: 'linear-gradient(135deg,#1d4ed8,#2563eb)', color: 'white', border: 'none', borderRadius: 40, padding: '13px 24px', fontWeight: 700, fontSize: 14, letterSpacing: '0.04em', cursor: 'pointer', whiteSpace: 'nowrap', boxShadow: '0 0 24px rgba(37,99,235,0.55),0 6px 20px rgba(0,0,0,0.45)', WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation', zIndex: 5 }}>
              <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg>
              View in AR
            </button>

            <div slot="poster" style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 14, background: 'transparent' }}>
              <div style={{ width: 40, height: 40, borderRadius: '50%', border: '3px solid rgba(59,130,246,0.15)', borderTop: '3px solid #3b82f6', animation: 'mv-spin 1s linear infinite' }} />
              <span style={{ color: '#6b7280', fontSize: 11, fontFamily: 'monospace', letterSpacing: '0.15em', textTransform: 'uppercase' }}>Loading model...</span>
              <style>{`@keyframes mv-spin { to { transform: rotate(360deg); } }`}</style>
            </div>
          </ModelViewer>

          <div style={{ borderTop: '1px solid rgba(255,255,255,0.06)', padding: '12px 14px', display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 7, position: 'relative', zIndex: 2 }}>
            {hasDims ? (
              <>
                <span style={{ fontSize: 9, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '0.1em', fontWeight: 700 }}>Dims:</span>
                {[{l:'W',v:dims.w},{l:'H',v:dims.h},{l:'D',v:dims.d}].map(d => (
                  <div key={d.l} style={{ display: 'flex', alignItems: 'baseline', gap: 3, background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 8, padding: '5px 9px' }}>
                    <span style={{ fontSize: 9, color: '#60a5fa', fontWeight: 700 }}>{d.l}</span>
                    <span style={{ fontSize: 13, color: 'white', fontFamily: 'monospace', fontWeight: 500 }}>{d.v}</span>
                    <span style={{ fontSize: 9, color: '#6b7280' }}>mm</span>
                  </div>
                ))}
                {dims.w && dims.d && (
                  <div style={{ display: 'flex', alignItems: 'baseline', gap: 3, background: 'rgba(37,99,235,0.1)', border: '1px solid rgba(37,99,235,0.2)', borderRadius: 8, padding: '5px 9px' }}>
                    <span style={{ fontSize: 9, color: '#60a5fa', fontWeight: 700 }}>Area</span>
                    <span style={{ fontSize: 13, color: '#93c5fd', fontFamily: 'monospace', fontWeight: 500 }}>{((Number(dims.w)/1000)*(Number(dims.d)/1000)).toFixed(2)}</span>
                    <span style={{ fontSize: 9, color: '#6b7280' }}>m²</span>
                  </div>
                )}
              </>
            ) : (
              <span style={{ fontSize: 10, color: '#6b7280', fontFamily: 'monospace' }}>Add dimensions to datasheet JSON</span>
            )}
          </div>
        </motion.div>
      )}

      {isActive && (
        <div className="flex items-start gap-3 bg-[#0066CC]/5 border border-[#0066CC]/15 rounded-2xl p-4">
          <div className="shrink-0 mt-0.5 text-[#0066CC]">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
            </svg>
          </div>
          <div>
            <p className="text-[11px] font-semibold text-[#0066CC] uppercase tracking-widest mb-0.5">AR Scale — Real Dimensions</p>
            <p className="text-[11px] text-[#86868B] leading-relaxed">
              In AR mode, the machine appears at its exact real-world scale (<code className="text-[#4DA6FF] bg-[#0066CC]/10 px-1 rounded">ar-scale=&quot;fixed&quot;</code>).
              Point your camera at a floor area of at least {hasDims ? `${(Number(dims.w||0)/1000).toFixed(1)}m × ${(Number(dims.d||0)/1000).toFixed(1)}m` : 'sufficient space'}.
              Use this to verify the machine fits your installation site before ordering.
            </p>
          </div>
        </div>
      )}
    </div>
  );
}

function nodeToSlug(title: string): string {
  return title.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-').replace(/^-+|-+$/g, '');
}

// ── SUBCOMPONENTE DE CASO DE ESTUDIO ──
function ExpandedCaseStudy({ node }: { node: any }) {
  const [activeTab, setActiveTab] = useState<"overview" | "tech-media">("overview");
  const nodeSlug = nodeToSlug(node.title);

  const [lightboxOpen, setLightboxOpen] = useState(false);
  const [lightboxImages, setLightboxImages] = useState<string[]>([]);
  const [lightboxInitialIndex, setLightboxInitialIndex] = useState(0);

  let specificDatasheet: any = {}; 
  let gallery: string[] = []; 
  let videos: string[] = [];
  let renders: string[] = [];
  try { 
    const parsed = JSON.parse(node.specificDatasheetJson || "{}");
    if (typeof parsed === 'object' && !Array.isArray(parsed)) specificDatasheet = parsed;
  } catch(e){}
  try { gallery = JSON.parse(node.galleryJson || "[]"); } catch(e){}
  try { videos = JSON.parse(node.videosJson || "[]"); } catch(e){}
  try { renders = JSON.parse(node.rendersJson || "[]"); } catch(e){}

  const hasTechMedia = node.model3DPath || renders.length > 0;
  const hasDatasheetData = specificDatasheet.model && specificDatasheet.specs && specificDatasheet.specs.length > 0;

  const usdzPath = node.model3DPath ? node.model3DPath.replace(/\.glb$/i, '.usdz') : '';

  const openLightbox = (clickedImageUrl: string) => {
    const allImages: string[] = [];
    if (node.projectOverview) {
      const regex = /!\[.*?\]\((.*?)\)/g;
      let match;
      while ((match = regex.exec(node.projectOverview)) !== null) {
        allImages.push(match[1]);
      }
    }
    gallery.forEach(img => allImages.push(`/cases/${nodeSlug}/${img}`));
    renders.forEach(ren => allImages.push(`/cases/${nodeSlug}/renders/${ren}`));
    if (!allImages.includes(clickedImageUrl)) {
      allImages.unshift(clickedImageUrl);
    }
    setLightboxImages(allImages);
    setLightboxInitialIndex(allImages.indexOf(clickedImageUrl));
    setLightboxOpen(true);
  };

  return (
    <div className="flex flex-col bg-white/50 dark:bg-black/40 backdrop-blur-xl rounded-b-[2.5rem] border-t border-black/5 dark:border-white/5 relative">
      
      <AnimatePresence>
        {lightboxOpen && (
          <ImageLightbox images={lightboxImages} initialIndex={lightboxInitialIndex} onClose={() => setLightboxOpen(false)} />
        )}
      </AnimatePresence>

      <div className="flex gap-8 px-8 pt-6 border-b border-black/5 dark:border-white/5 overflow-x-auto [scrollbar-width:none]">
        <button onClick={() => setActiveTab("overview")} className={`pb-4 text-xs uppercase tracking-widest font-semibold flex items-center gap-2 transition-all border-b-2 whitespace-nowrap ${activeTab === "overview" ? "text-[#0066CC] dark:text-[#00F0FF] border-[#0066CC] dark:border-[#00F0FF]" : "text-[#86868B] border-transparent hover:text-[#1D1D1F] dark:hover:text-white"}`}>
          <FileText size={16}/> Project Overview
        </button>
        {hasTechMedia && (
          <button onClick={() => setActiveTab("tech-media")} className={`pb-4 text-xs uppercase tracking-widest font-semibold flex items-center gap-2 transition-all border-b-2 whitespace-nowrap ${activeTab === "tech-media" ? "text-[#0066CC] dark:text-[#00F0FF] border-[#0066CC] dark:border-[#00F0FF]" : "text-[#86868B] border-transparent hover:text-[#1D1D1F] dark:hover:text-white"}`}>
            <Box size={16}/> 3D & Technical Renders
          </button>
        )}
      </div>

      <div className="p-4 md:p-12">
        {activeTab === "overview" && (
          <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="flex flex-col gap-16">
            
            {node.projectOverview && (
              <div className="max-w-none">
                {renderMarkdown(node.projectOverview, openLightbox)}
              </div>
            )}

            {(videos.length > 0 || gallery.length > 0) && (
              <div className="space-y-8">
                <h5 className="text-lg font-medium text-[#1D1D1F] dark:text-white flex items-center gap-2 border-b border-black/5 dark:border-white/5 pb-4">
                  <Play size={18} className="text-[#0066CC] dark:text-[#00F0FF]"/> Installation Media
                </h5>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                  {videos.map((vid: string, idx: number) => {
                    const isLocalMp4 = vid.endsWith('.mp4');
                    const videoSrc = isLocalMp4 && !vid.startsWith('http') ? `/cases/${nodeSlug}/videos/${vid}` : vid;
                    return (
                      <div key={`v-${idx}`} className="relative w-full aspect-video rounded-2xl md:rounded-3xl overflow-hidden border border-black/10 dark:border-white/10 shadow-xl bg-black col-span-1 md:col-span-2">
                        {isLocalMp4 ? (
                          <AutoPlayVideo src={videoSrc} className="absolute inset-0 w-full h-full object-contain" />
                        ) : (
                          <iframe src={videoSrc} className="absolute inset-0 w-full h-full" allowFullScreen title={`Video ${idx + 1}`} />
                        )}
                      </div>
                    );
                  })}

                  {gallery.map((img: string, idx: number) => {
                    const fullImgSrc = `/cases/${nodeSlug}/${img}`;
                    return (
                      <div key={`g-${idx}`} className="relative w-full aspect-video rounded-2xl md:rounded-3xl overflow-hidden border border-black/10 dark:border-white/10 shadow-lg group bg-white">
                        <Image src={fullImgSrc} alt="Installation" fill sizes="(max-width: 768px) 100vw, 50vw" className="object-cover group-hover:scale-105 transition-transform duration-700" />
                        <button
                          onClick={() => openLightbox(fullImgSrc)}
                          className="absolute inset-0 w-full h-full bg-black/0 hover:bg-black/30 active:bg-black/40 transition-all flex items-center justify-center opacity-0 group-hover:opacity-100 backdrop-blur-[0px] hover:backdrop-blur-sm touch-manipulation"
                          aria-label="Ver imagen completa"
                        >
                          <span className="bg-black/50 backdrop-blur-md rounded-full p-4 scale-90 group-hover:scale-100 transition-transform">
                            <Maximize size={28} className="text-white" />
                          </span>
                        </button>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}

            {hasDatasheetData && (
              <div className="w-full bg-[#1D1D1F] dark:bg-[#0A0A0C] text-[#F5F5F7] p-6 md:p-12 rounded-2xl md:rounded-[2.5rem] shadow-2xl relative overflow-hidden group">
                <div className="absolute inset-0 bg-[linear-gradient(to_bottom,transparent_0%,rgba(0,102,204,0.05)_50%,transparent_100%)] animate-scan-slow pointer-events-none hidden group-hover:block"></div>
                <div className="absolute top-0 right-0 p-12 opacity-10 pointer-events-none transition-opacity group-hover:opacity-20"><Cpu size={200} /></div>
                
                <h3 className="text-sm font-semibold text-[#00F0FF] uppercase tracking-widest mb-3 transition-colors flex items-center gap-2">
                  <span className="w-2 h-2 bg-[#00F0FF] rounded-full animate-pulse"></span> Technical Datasheet
                </h3>
                <h4 className="text-2xl md:text-4xl font-light mb-10 font-mono tracking-tight text-white">{specificDatasheet.model}</h4>

                <div className="grid grid-cols-2 md:grid-cols-4 gap-y-10 gap-x-6 relative z-10 font-mono text-sm">
                  {specificDatasheet.specs.map((spec: any, idx: number) => {
                    if (spec.highlight) {
                      return (
                        <div key={idx} className="col-span-2 p-4 bg-white/5 rounded-2xl border border-white/10 flex flex-col justify-center shadow-inner">
                          <span className="block text-[10px] text-[#86868B] uppercase tracking-widest mb-2 flex items-center gap-2">
                            <Zap size={12} className="text-[#00F0FF]"/> {spec.label}
                          </span>
                          <span className="block text-[#00F0FF] text-xl md:text-2xl font-bold drop-shadow-[0_0_12px_rgba(0,240,255,0.4)]">
                            {spec.value}
                          </span>
                        </div>
                      );
                    }
                    return (
                      <div key={idx} className="col-span-2 md:col-span-1">
                        <span className="block text-[10px] text-[#86868B] uppercase tracking-widest mb-2">{spec.label}</span>
                        <span className="block text-white text-sm">{spec.value}</span>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
          </motion.div>
        )}

        {activeTab === "tech-media" && (
          <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="space-y-12">
            
            {node.model3DPath && (
              <TechnicalViewer3D node={node} usdzPath={usdzPath} />
            )}

            {renders.length > 0 && (
              <div>
                <h5 className="text-lg font-medium text-[#1D1D1F] dark:text-white mb-6 flex items-center gap-2 border-b border-black/5 dark:border-white/5 pb-4">
                  <PencilRuler size={18} className="text-purple-500"/> Engineering Renders
                </h5>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                  {renders.map((ren: string, idx: number) => {
                    const fullRenSrc = `/cases/${nodeSlug}/renders/${ren}`;
                    return (
                      <div key={idx} className="relative w-full aspect-[4/3] rounded-2xl md:rounded-3xl overflow-hidden border border-black/10 dark:border-white/10 shadow-lg group bg-white dark:bg-[#1a1a1a]">
                        <Image src={fullRenSrc} alt="Technical Render" fill className="object-contain group-hover:scale-105 transition-transform duration-700" sizes="(max-width: 768px) 100vw, 50vw" />
                        <button
                          onClick={() => openLightbox(fullRenSrc)}
                          className="absolute inset-0 w-full h-full bg-black/0 hover:bg-black/20 active:bg-black/30 transition-all flex items-center justify-center opacity-0 group-hover:opacity-100 backdrop-blur-[0px] hover:backdrop-blur-sm touch-manipulation"
                          aria-label="Ver render completo"
                        >
                          <span className="bg-black/50 backdrop-blur-md rounded-full p-4 scale-90 group-hover:scale-100 transition-transform">
                            <Maximize size={28} className="text-white" />
                          </span>
                        </button>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
          </motion.div>
        )}
      </div>
    </div>
  );
}

// --- COMPONENTE PRINCIPAL ---
export default function ApplicationClient({ data, realCases, images, breadcrumbs }: { data: any, realCases: any[], images: any, breadcrumbs?: BreadcrumbItem[] }) {
  const [expandedCase, setExpandedCase] = useState<string | null>(null);

  const [mainLightboxOpen, setMainLightboxOpen] = useState(false);
  const [mainLightboxImages, setMainLightboxImages] = useState<string[]>([]);
  const [mainLightboxInitialIndex, setMainLightboxInitialIndex] = useState(0);

  const sections = JSON.parse(data.sectionsJson || "[]");
  const advantages = JSON.parse(data.advantagesJson || "[]");
  const { heroImage, blueprints, machines } = images;

  const openMainLightbox = (clickedImageUrl: string) => {
    const allImages: string[] = [];
    if (data.heroDescription) {
      const regex = /!\[.*?\]\((.*?)\)/g;
      let match;
      while ((match = regex.exec(data.heroDescription)) !== null) {
        allImages.push(match[1]);
      }
    }
    if (!allImages.includes(clickedImageUrl)) {
      allImages.unshift(clickedImageUrl);
    }
    setMainLightboxImages(allImages);
    setMainLightboxInitialIndex(allImages.indexOf(clickedImageUrl));
    setMainLightboxOpen(true);
  };

  return (
    <main className="relative min-h-screen pb-24 bg-[#F5F5F7] dark:bg-[#050505] transition-colors duration-500">
      <BreathingField />

      <AnimatePresence>
        {mainLightboxOpen && (
          <ImageLightbox images={mainLightboxImages} initialIndex={mainLightboxInitialIndex} onClose={() => setMainLightboxOpen(false)} />
        )}
      </AnimatePresence>

      <div className="fixed top-24 left-6 z-50 hidden md:block">
        <Link href="/#applications-deep" className="inline-flex items-center gap-2 text-sm font-medium text-[#86868B] hover:text-[#0066CC] dark:hover:text-[#00F0FF] transition-colors py-2 px-4 bg-white/80 dark:bg-black/50 backdrop-blur-md rounded-full group border border-black/5 dark:border-white/10 shadow-lg">
          <ArrowLeft size={16} className="group-hover:-translate-x-1 transition-transform" /> Back to Overview
        </Link>
      </div>

      <section className="relative w-full h-[50vh] md:h-[70vh] flex items-end justify-start overflow-hidden">
        {heroImage ? (
          <Image src={heroImage} alt={data.title} fill sizes="100vw" className="object-cover object-center scale-105 animate-slow-zoom" priority />
        ) : (
          <div className="absolute inset-0 bg-gradient-to-br from-[#0066CC]/20 to-black/80" />
        )}
        <div className="absolute inset-0 bg-gradient-to-t from-[#F5F5F7] via-[#F5F5F7]/80 dark:from-[#0A0A0C] dark:via-[#0A0A0C]/80 to-transparent transition-colors duration-500" />
        
        <div className="relative z-10 max-w-4xl mx-auto px-6 pb-12 md:pb-16 w-full">
          <header>
            {breadcrumbs && <Breadcrumbs items={breadcrumbs} />}
            <div className="inline-flex items-center gap-2 text-[#0066CC] dark:text-[#00F0FF] mb-3 bg-white/80 dark:bg-black/80 backdrop-blur-sm px-3 py-1.5 rounded-full border border-black/5 dark:border-white/10">
              <LayoutDashboard size={14} />
              <span className="text-[10px] md:text-xs font-semibold uppercase tracking-widest">{data.category}</span>
            </div>
            <h1 className="text-4xl md:text-6xl font-light text-[#1D1D1F] dark:text-[#F5F5F7] tracking-tighter mb-3 transition-colors drop-shadow-sm">
              {data.title}
            </h1>
            <h2 className="text-lg md:text-2xl font-light text-[#1D1D1F]/80 dark:text-[#F5F5F7]/80 transition-colors max-w-2xl leading-normal">
              {data.subtitle}
            </h2>
          </header>
        </div>
      </section>
        
      <div className="max-w-4xl mx-auto px-6 relative z-10 mt-6">
        
        <div className="mb-20">
          <div className="max-w-none">
            {renderMarkdown(data.heroDescription, openMainLightbox)}
          </div>
        </div>

        {sections.length > 0 && (
          <div className="space-y-12 mb-20">
            {sections.map((section: any, idx: number) => (
              <div key={idx} className="bg-white/60 dark:bg-[#1D1D1F]/40 backdrop-blur-2xl border border-black/5 dark:border-white/10 p-6 md:p-10 rounded-2xl md:rounded-[2.5rem] shadow-sm transition-colors relative overflow-hidden">
                {section.isMainTech && <div className="absolute top-0 right-0 w-32 h-32 bg-gradient-to-br from-[#0066CC]/20 dark:from-[#00F0FF]/10 to-transparent blur-3xl -z-10" />}
                <div className="mb-6 flex flex-col md:flex-row md:items-center gap-2 md:gap-4">
                  {section.isMainTech && (
                    <span className="w-fit text-[9px] md:text-[10px] bg-[#0066CC] dark:bg-[#00F0FF] text-white dark:text-black px-2.5 py-1 rounded-full uppercase tracking-widest font-bold shadow-sm whitespace-nowrap">
                      Main Tech
                    </span>
                  )}
                  <h3 className="text-xl md:text-2xl font-medium text-[#1D1D1F] dark:text-[#F5F5F7] transition-colors leading-tight">
                    {section.title}
                  </h3>
                </div>
                <ul className="space-y-4">
                  {section.items.map((item: any, i: number) => (
                    <li key={i} className="flex flex-col md:flex-row gap-1.5 md:gap-5 pb-4 border-b border-black/5 dark:border-white/5 last:border-0 last:pb-0 transition-colors group">
                      <span className="text-[#86868B] dark:text-[#A1A1A6] font-medium min-w-[180px] shrink-0 transition-colors group-hover:text-[#0066CC] dark:group-hover:text-[#00F0FF] text-sm">
                        {item.label}
                      </span>
                      <span className="text-[#1D1D1F] dark:text-[#F5F5F7] font-light leading-relaxed transition-colors whitespace-pre-line text-sm">
                        {item.content}
                      </span>
                    </li>
                  ))}
                </ul>
              </div>
            ))}
          </div>
        )}

        {advantages.length > 0 && (
          <div className="mb-20">
            <div className="flex items-center gap-3 mb-8">
              <div className="p-2 rounded-xl bg-[#0066CC]/10 dark:bg-[#00F0FF]/10 text-[#0066CC] dark:text-[#00F0FF]"><Zap size={20} /></div>
              <h3 className="text-2xl md:text-3xl font-light text-[#1D1D1F] dark:text-[#F5F5F7] transition-colors">The FLUX Advantage</h3>
            </div>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
              {advantages.map((adv: any, idx: number) => (
                <div key={idx} className="bg-white/50 dark:bg-[#1D1D1F]/60 backdrop-blur-md border border-black/5 dark:border-white/10 p-6 rounded-2xl transition-all hover:shadow-md hover:-translate-y-1 group">
                  <CheckCircle2 size={20} className="text-[#0066CC] dark:text-[#00F0FF] mb-3 group-hover:scale-110 transition-transform" />
                  <h4 className="text-lg font-medium text-[#1D1D1F] dark:text-[#F5F5F7] mb-2 transition-colors">{adv.title}</h4>
                  <p className="text-sm text-[#86868B] dark:text-[#A1A1A6] font-light leading-relaxed transition-colors whitespace-pre-line">{adv.description}</p>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>

      {realCases.length > 0 && (
        <section className="relative z-10 px-6 max-w-6xl mx-auto pt-12 mt-12 border-t border-black/10 dark:border-white/10">
          <div className="mb-10 border-b border-black/5 dark:border-white/5 pb-6 flex items-center justify-between">
            <div>
              <h3 className="text-3xl md:text-4xl font-light text-[#1D1D1F] dark:text-white flex items-center gap-3 transition-colors mb-2">
                <Factory className="text-[#0066CC] dark:text-[#00F0FF]" size={30} /> Proven Solutions
              </h3>
              <p className="text-base text-[#86868B]">Real-world implementations of our customized technology.</p>
            </div>
            <div className="hidden md:flex items-center gap-2 text-xs font-semibold uppercase tracking-widest text-[#0066CC] dark:text-[#00F0FF] bg-[#0066CC]/10 dark:bg-[#00F0FF]/10 px-4 py-2.5 rounded-full border border-[#0066CC]/20 dark:border-[#00F0FF]/20">
              <CheckCircle2 size={16} /> {realCases.length} Installations
            </div>
          </div>

          <div className="flex flex-col gap-6">
            {realCases.map((node) => {
              const isExpanded = expandedCase === node.id;
              return (
                <div key={node.id} className="bg-white/80 dark:bg-[#111]/90 backdrop-blur-2xl border border-black/10 dark:border-white/10 rounded-2xl md:rounded-[2.5rem] overflow-hidden transition-all duration-500 shadow-xl">
                  <div onClick={() => setExpandedCase(isExpanded ? null : node.id)} className="p-5 md:p-8 cursor-pointer flex flex-col md:flex-row items-start md:items-center justify-between gap-5 group hover:bg-black/5 dark:hover:bg-white/[0.02] transition-colors">
                    <div className="flex items-center gap-5 flex-1">
                      <div className="w-16 h-16 md:w-20 md:h-20 rounded-2xl md:rounded-3xl bg-black/5 dark:bg-black/50 border border-black/10 dark:border-white/5 flex items-center justify-center shrink-0 overflow-hidden relative shadow-inner">
                        {node.mediaFileName ? (
                          <Image src={`/cases/${nodeToSlug(node.title)}/${node.mediaFileName}`} alt={node.title} fill sizes="100px" className="object-cover opacity-90 group-hover:scale-110 transition-transform duration-700" />
                        ) : (
                          <Cpu size={28} className="text-[#0066CC]/50 dark:text-[#00F0FF]/50" />
                        )}
                      </div>
                      <div>
                        <h4 className="text-xl md:text-2xl font-medium text-[#1D1D1F] dark:text-white group-hover:text-[#0066CC] dark:group-hover:text-[#00F0FF] transition-colors tracking-tight">{node.title}</h4>
                        <span className="text-sm text-[#86868B] flex items-center gap-1.5 mt-1.5">
                          <MapPin size={14} /> {node.location}
                        </span>
                      </div>
                    </div>
                    <div className="flex items-center gap-5 w-full md:w-auto">
                      {node.energySavings && (
                        <div className="bg-[#0066CC]/10 dark:bg-[#00F0FF]/10 border border-[#0066CC]/20 dark:border-[#00F0FF]/20 px-5 py-2.5 rounded-xl text-center flex-1 md:flex-none">
                          <span className="block text-[9px] uppercase tracking-widest text-[#0066CC] dark:text-[#00F0FF] font-semibold mb-0.5">Highlight</span>
                          <span className="block text-base font-medium text-[#1D1D1F] dark:text-white">{node.energySavings}</span>
                        </div>
                      )}
                      <button className={`w-12 h-12 rounded-full flex items-center justify-center shrink-0 transition-transform duration-500 shadow-md ${isExpanded ? 'bg-[#0066CC] dark:bg-[#00F0FF] text-white dark:text-black rotate-180' : 'bg-white dark:bg-white/10 text-[#1D1D1F] dark:text-white border border-black/10 dark:border-transparent group-hover:scale-105'}`}>
                        <ChevronDown size={22} />
                      </button>
                    </div>
                  </div>
                  <AnimatePresence>
                    {isExpanded && (
                      <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: "auto", opacity: 1 }} exit={{ height: 0, opacity: 0 }} transition={{ duration: 0.5, ease: [0.16, 1, 0.3, 1] }}>
                        <ExpandedCaseStudy node={node} />
                      </motion.div>
                    )}
                  </AnimatePresence>
                </div>
              );
            })}
          </div>
        </section>
      )}
    </main>
  );
}