/* ============================================================
   lomi — componentes UI compartidos
   ============================================================ */
const { useState, useEffect, useRef, useCallback, useMemo } = React;

/* ---------- iconos (línea simple) ---------- */
function Icon({ name, size = 22, stroke = 2 }) {
  const s = { width: size, height: size, fill: "none", stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
  const paths = {
    search: <><circle cx="11" cy="11" r="7" /><line x1="16.5" y1="16.5" x2="21" y2="21" /></>,
    cart: <><circle cx="9" cy="20" r="1.6" /><circle cx="18" cy="20" r="1.6" /><path d="M2 3h3l2.2 12.2a1.5 1.5 0 0 0 1.5 1.2h8.4a1.5 1.5 0 0 0 1.5-1.2L21.5 7H6" /></>,
    user: <><circle cx="12" cy="8" r="4" /><path d="M4 21c0-4 3.6-6.5 8-6.5s8 2.5 8 6.5" /></>,
    heart: <path d="M12 20s-7-4.5-9.5-9C1 8 2.5 4.5 6 4.5c2 0 3.2 1.2 4 2.4.8-1.2 2-2.4 4-2.4 3.5 0 5 3.5 3.5 6.5C19 15.5 12 20 12 20z" />,
    menu: <><line x1="3" y1="7" x2="21" y2="7" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="17" x2="21" y2="17" /></>,
    close: <><line x1="6" y1="6" x2="18" y2="18" /><line x1="18" y1="6" x2="6" y2="18" /></>,
    arrow: <><line x1="4" y1="12" x2="20" y2="12" /><polyline points="14 6 20 12 14 18" /></>,
    back: <><line x1="20" y1="12" x2="4" y2="12" /><polyline points="10 6 4 12 10 18" /></>,
    star: <path d="M12 3l2.6 5.3 5.9.9-4.2 4.1 1 5.8L12 16.9 6.7 19l1-5.8-4.2-4.1 5.9-.9z" />,
    truck: <><rect x="1" y="6" width="13" height="11" rx="1.5" /><path d="M14 9h4l3 3v5h-7" /><circle cx="6" cy="18.5" r="1.8" /><circle cx="17.5" cy="18.5" r="1.8" /></>,
    shield: <path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z" />,
    chat: <path d="M21 12a8 8 0 0 1-11.5 7.2L4 21l1.8-5.2A8 8 0 1 1 21 12z" />,
    plus: <><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></>,
    minus: <line x1="5" y1="12" x2="19" y2="12" />,
    check: <polyline points="4 12 10 18 20 6" />,
    rotate: <><path d="M4 12a8 8 0 0 1 13.5-5.8L20 8" /><polyline points="20 3 20 8 15 8" /><path d="M20 12a8 8 0 0 1-13.5 5.8L4 16" /><polyline points="4 21 4 16 9 16" /></>,
    paw: <><circle cx="7" cy="9" r="1.8" /><circle cx="12" cy="7" r="1.8" /><circle cx="17" cy="9" r="1.8" /><circle cx="9.5" cy="13" r="1.5" /><circle cx="14.5" cy="13" r="1.5" /><path d="M8 18.5c0-2.2 1.8-3.5 4-3.5s4 1.3 4 3.5-1.8 2.5-4 2.5-4-.3-4-2.5z" /></>,
    bolt: <path d="M13 2 4 14h7l-1 8 9-12h-7z" />,
    leaf: <path d="M5 19c0-8 6-14 14-14 0 8-6 14-14 14zM5 19c4-4 7-6 11-7" />,
    bowl: <><path d="M3 11h18a9 9 0 0 1-18 0z" /><path d="M7 7c0-1.5 1-2.5 2-2.5M12 6c0-1.5 1-2.5 2-2.5M17 7c0-1.5 1-2.5 2-2.5" /></>,
    ball: <><circle cx="12" cy="12" r="9" /><path d="M3.5 9h17M5 16h14M9 3.5c-2 5-2 12 0 17M15 3.5c2 5 2 12 0 17" /></>,
    collar: <><circle cx="12" cy="12" r="8" /><path d="M9 19l3 3 3-3" /><circle cx="12" cy="22" r="0" /></>,
    drop: <path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11z" />,
    cross: <path d="M9 3h6v6h6v6h-6v6H9v-6H3V9h6z" />,
    bone: <path d="M5 9a2.2 2.2 0 1 1 2.8-3 2.2 2.2 0 0 1 3.2 0h2a2.2 2.2 0 0 1 3.2 0A2.2 2.2 0 1 1 19 9a2.2 2.2 0 1 1-2.8 3 2.2 2.2 0 0 1-3.2 0h-2a2.2 2.2 0 0 1-3.2 0A2.2 2.2 0 1 1 5 9z" />,
    spark: <path d="M12 3l1.8 5.4L19 10l-5.2 1.6L12 17l-1.8-5.4L5 10l5.2-1.6z" />,
    image: <><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></>,
  };
  return <svg viewBox="0 0 24 24" style={s}>{paths[name] || null}</svg>;
}

/* ---------- logo ---------- */
function Logo({ onClick, light }) {
  const cfg  = (window.LOMI_DATA && window.LOMI_DATA.settings) || {};
  const customLogo = cfg.logo_url || '';
  const siteName   = cfg.site_name || 'lomi';
  return (
    <button className="logo" onClick={onClick} aria-label={siteName + ' inicio'}>
      {customLogo ? (
        <img
          src={customLogo}
          alt={siteName}
          style={{
            height: 34, maxWidth: 160, objectFit: 'contain', display: 'block',
            filter: light ? 'brightness(0) invert(1)' : undefined,
          }}
        />
      ) : (
        <>
          <span className="logo-mark" style={{ color: light ? "#fff" : undefined }}>
            <svg viewBox="0 0 40 40" width="34" height="34">
              <circle cx="20" cy="21" r="17" fill="var(--coral)" />
              <g fill="#fff">
                <circle cx="13" cy="17" r="2.7" /><circle cx="20" cy="14.5" r="2.7" />
                <circle cx="27" cy="17" r="2.7" />
                <path d="M13 27c0-3.5 3-5.5 7-5.5s7 2 7 5.5-3 4-7 4-7-.5-7-4z" />
              </g>
            </svg>
          </span>
          <span className="logo-word" style={{ color: light ? "#fff" : undefined }}>{siteName}</span>
        </>
      )}
    </button>
  );
}


/* ---------- estrellas ---------- */
function Stars({ value, size = 14 }) {
  return (
    <span className="stars" style={{ "--s": size + "px" }}>
      {[0, 1, 2, 3, 4].map((i) => (
        <span key={i} className="star" style={{ color: i < Math.round(value) ? "var(--sun-deep, #e0a93b)" : "var(--line-2)" }}>
          <Icon name="star" size={size} stroke={0} />
        </span>
      ))}
    </span>
  );
}

/* ---------- placeholder / imagen de producto ---------- */
function ProductImage({ product, big }) {
  const cat = window.LOMI_DATA.CATEGORIES.find((c) => c.id === product.category);

  // Intentar obtener imagen real
  const realImages = useMemo(() => {
    try { return JSON.parse(product.images || '[]'); } catch { return []; }
  }, [product.images]);
  const firstImage = realImages[0] || product.image_url || null;

  if (firstImage) {
    return (
      <div className="prod-img" style={{
        background: `radial-gradient(120% 120% at 50% 50%, ${product.tint}44, ${product.tint}22 60%, ${product.tint}11)`,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <img
          src={firstImage}
          alt={product.name}
          style={{ width: '100%', height: '100%', objectFit: 'contain', padding: big ? 24 : 14 }}
          onError={e => { e.target.style.display = 'none'; }}
          loading="lazy"
        />
        {product.badge && <span className={"prod-badge " + (product.badge === "Oferta" ? "is-sale" : "")}>{product.badge}</span>}
      </div>
    );
  }

  // Fallback: glifo con gradiente
  return (
    <div className="prod-img" style={{ background: `radial-gradient(120% 120% at 30% 20%, ${product.tint}cc, ${product.tint}66 60%, ${product.tint}33)` }}>
      <div className="prod-img-glow" />
      <div className="prod-glyph" style={{ color: "rgba(255,255,255,0.55)" }}>
        <Icon name={cat ? cat.icon : "paw"} size={big ? 130 : 76} stroke={1.4} />
      </div>
      {product.badge && <span className={"prod-badge " + (product.badge === "Oferta" ? "is-sale" : "")}>{product.badge}</span>}
    </div>
  );
}

/* ---------- tarjeta de producto ---------- */
function ProductCard({ product, onOpen, onAdd, idx = 0, favorites, onToggleFavorite }) {
  const [added, setAdded] = useState(false);
  const [hovered, setHovered] = useState(false);
  const petLabel = product.pet === "perro" ? "Perro" : product.pet === "gato" ? "Gato" : "Perro · Gato";
  const outOfStock = product.stock === 0;
  const isFav = favorites && favorites.includes(product.id);

  const hasVideo = !!product.video_url;
  const isYT = hasVideo && (product.video_url.includes('youtube') || product.video_url.includes('youtu.be'));
  const videoSrc = isYT
    ? product.video_url.replace('watch?v=','embed/').replace('youtu.be/','youtube.com/embed/') + '?autoplay=1&mute=1&loop=1&controls=0&rel=0&playsinline=1'
    : product.video_url;

  return (
    <article className="pcard reveal" style={{ transitionDelay: (idx % 4) * 0.05 + "s" }} onClick={() => onOpen(product)}
      onMouseEnter={() => hasVideo && setHovered(true)}
      onMouseLeave={() => hasVideo && setHovered(false)}
    >
      <div style={{ position:'relative' }}>
        {hasVideo && hovered ? (
          <div className="prod-img" style={{ background:'#000', overflow:'hidden' }}>
            {product.badge && <span className={"prod-badge " + (product.badge === "Oferta" ? "is-sale" : "")} style={{ zIndex:3 }}>{product.badge}</span>}
            {isYT ? (
              <iframe src={videoSrc} style={{ width:'100%', height:'100%', border:'none' }} allow="autoplay; encrypted-media" title={product.name} />
            ) : (
              <video src={videoSrc} autoPlay muted loop playsInline style={{ width:'100%', height:'100%', objectFit:'cover' }} />
            )}
            <div style={{ position:'absolute', bottom:8, right:8, background:'rgba(0,0,0,0.6)', color:'#fff', fontSize:11, padding:'2px 8px', borderRadius:20, fontWeight:600, zIndex:2 }}>
              ▶ Video
            </div>
          </div>
        ) : (
          <ProductImage product={product} />
        )}
        {hasVideo && !hovered && (
          <div style={{ position:'absolute', bottom:8, left:8, background:'rgba(0,0,0,0.55)', color:'#fff', fontSize:10, padding:'2px 7px', borderRadius:20, fontWeight:600, display:'flex', alignItems:'center', gap:4, zIndex:2, pointerEvents:'none' }}>
            <span>▶</span> Video
          </div>
        )}
        {onToggleFavorite && (
          <button
            className={"pcard-heart " + (isFav ? "on" : "")}
            onClick={e => { e.stopPropagation(); onToggleFavorite(product.id); }}
            aria-label={isFav ? "Quitar de favoritos" : "Agregar a favoritos"}
          >
            <Icon name="heart" size={17} stroke={isFav ? 0 : 2} />
          </button>
        )}
      </div>
      <div className="pcard-body">
        <div className="pcard-meta">
          <span className="pcard-brand">{product.brand}</span>
          <span className="pcard-pet">{petLabel}</span>
        </div>
        <h3 className="pcard-name">{product.name}</h3>
        <div className="pcard-rate"><Stars value={product.rating} /><span>{product.rating} · {product.reviews}</span></div>
        <div className="pcard-foot">
          <div className="pcard-price">
            {!outOfStock && product.oldPrice && <span className="price-old">{window.formatCLP(product.oldPrice)}</span>}
            {outOfStock
              ? <span className="price-oos">Agotado</span>
              : <span className="price-now">{window.formatCLP(product.price)}</span>
            }
          </div>
          <button
            className={"pcard-add " + (added ? "is-added" : "")}
            onClick={(e) => { e.stopPropagation(); if (!outOfStock) { onAdd(product); setAdded(true); setTimeout(() => setAdded(false), 1100); } }}
            disabled={outOfStock}
            aria-label={outOfStock ? "Sin stock" : "Agregar al carro"}
          >
            <Icon name={added ? "check" : "plus"} size={20} />
          </button>
        </div>
      </div>
    </article>
  );
}

/* ---------- reveal on scroll (hook) ---------- */
function useReveal(dep) {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal:not(.in)");
    const io = new IntersectionObserver((entries) => {
      entries.forEach((en) => { if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, [dep]);
}

/* ---------- canvas Three.js reutilizable ---------- */
function ThreeCanvas({ factory, className, style, onReady }) {
  const ref = useRef(null);
  const ctrl = useRef(null);
  useEffect(() => {
    if (!ref.current || !window.LOMI3D) return;
    let c;
    try { c = factory(ref.current); ctrl.current = c; if (onReady) onReady(c); }
    catch (e) { console.error("3D init", e); }
    return () => { if (c && c.dispose) c.dispose(); };
  }, []);
  return <canvas ref={ref} className={className} style={style} />;
}

Object.assign(window, { Icon, Logo, ThreeCanvas, Stars, ProductImage, ProductCard, useReveal });
