// ============================================================
// LGM — Componentes de propiedades (cards, carrusel, grid, modal)
// ============================================================
const { useState: useStateP, useEffect: useEffectP, useRef: useRefP, useMemo: useMemoP } = React;

// ============================================================
// PROPERTY CARD (carrusel)
// ============================================================
function PCard({ p, t, onOpen, isFav, onFav }) {
  const firstImg = p.images[0];
  return (
    <article className="pcard" onClick={() => onOpen(p)}>
      <div className="pcard__img">
        <img src={firstImg} alt={p.name} loading="lazy" />
        <div className="pcard__badges">
          {p.operation === "sale" && <span className="pcard__badge pcard__badge--gold">{t.editorial.sale}</span>}
          {p.operation === "rent" && <span className="pcard__badge">{t.editorial.rent}</span>}
          {p.operation === "vacation" && <span className="pcard__badge pcard__badge--vacation">{t.editorial.vacation}</span>}
          {p.featured && <span className="pcard__badge">★</span>}
        </div>
        <button className={`pcard__fav${isFav ? " active" : ""}`}
          onClick={(e) => { e.stopPropagation(); onFav(p.id); }}>
          <Icon.Heart fill={isFav ? "currentColor" : "none"} />
        </button>
      </div>
      <div className="pcard__body">
        <div className="pcard__ref">{t.prop.ref} {p.ref}</div>
        <h3 className="pcard__name">{p.name}</h3>
        <div className="pcard__zone">{p.zone ? (<>{p.zone}<span className="dot">·</span>{p.city}</>) : p.city}</div>
        <div className="pcard__specs">
          <div><Icon.Bed /> {p.beds} {t.prop.beds}</div>
          <div><Icon.Bath /> {p.baths}</div>
          <div><Icon.Car /> {p.parking}</div>
          <div><Icon.Area /> {p.area}m²</div>
        </div>
        <div className="pcard__price">
          <span className="pcard__price-main">
            {p.price ? formatPrice(p.price) : formatRent(p.rent)}
          </span>
          {p.operation === "vacation" && p.rent && (
            <span className="pcard__price-alt">{formatRent(p.rent)} / noche</span>
          )}
        </div>
      </div>
    </article>
  );
}

// ============================================================
// FEATURED CARD V2 (screenshot redesign)
// ============================================================
function FCard({ p, onOpen, isFav, onFav, corner }) {
  const firstImg = p.images[0];
  const priceLabel = p.operation === "rent"
    ? `${formatRent(p.rent)}/mes`
    : p.price ? formatPrice(p.price) : formatRent(p.rent);
  const locUpper = [p.zone, p.city].filter(Boolean).join(", ").toUpperCase();
  const typeLabel = ({
    villa: "Villa",
    apartment: "Apartamento",
    penthouse: "Penthouse",
    estate: "Estate",
    land: "Terreno",
    commercial: "Comercial",
  })[p.type] || "Propiedad";

  return (
    <article className="fcard reveal" onClick={() => onOpen(p)}>
      <div className="fcard__img">
        <img src={firstImg} alt={p.name} loading="lazy" />
        <div className="fcard__shade" />
        {corner && <span className="fcard__corner">{corner}</span>}
        <button className={`fcard__fav${isFav ? " active" : ""}`}
          onClick={(e) => { e.stopPropagation(); onFav(p.id); }}
          aria-label="Favorito">
          <Icon.Heart fill={isFav ? "currentColor" : "none"} />
        </button>
        <div className="fcard__over">
          <div className="fcard__loc">{locUpper}</div>
          <h3 className="fcard__name">{p.name}</h3>
          <div className="fcard__price">{priceLabel}</div>
          <div className="fcard__meta">
            <span>{p.area}m²</span>
            <span>{typeLabel}</span>
          </div>
        </div>
      </div>
    </article>
  );
}

// ============================================================
// FEATURED CAROUSEL V2
// ============================================================
function FeaturedCarousel({ t, properties, onOpen, favorites, onFav, onViewAll }) {
  const trackRef = useRefP(null);
  const [filter, setFilter] = useStateP("all");
  const [activeDot, setActiveDot] = useStateP(0);

  // Filter logic
  const filtered = useMemoP(() => {
    return properties.filter(p => {
      if (filter === "all") return true;
      if (filter === "villa") return p.type === "villa" || p.type === "house";
      if (filter === "apartment") return p.type === "apartment" || p.type === "penthouse";
      if (filter === "land") return p.type === "land";
      if (filter === "commercial") return p.type === "commercial";
      if (filter === "ultra") return (p.price || 0) > 1500000;
      return true;
    });
  }, [properties, filter]);

  // Corner badge decision
  const cornerFor = (p) => {
    if ((p.price || 0) > 1500000) return "LUJO";
    if (p.year && p.year >= 2023) return "NUEVO";
    if (p.featured) return "EXCLUSIVA";
    return null;
  };

  // Scroll → dot index
  const update = () => {
    const el = trackRef.current; if (!el) return;
    const max = el.scrollWidth - el.clientWidth;
    const pct = max > 0 ? el.scrollLeft / max : 0;
    setActiveDot(Math.round(pct * 4)); // 5 dots
  };

  useEffectP(() => {
    const el = trackRef.current; if (!el) return;
    update();
    el.addEventListener("scroll", update, { passive: true });
    window.addEventListener("resize", update);
    return () => { el.removeEventListener("scroll", update); window.removeEventListener("resize", update); };
  }, [filtered.length]);

  // Drag to scroll — desktop only (touch usa swipe nativo con scroll-snap)
  useEffectP(() => {
    const el = trackRef.current; if (!el) return;
    // Skip on touch/coarse-pointer devices: mobile y tablet usan swipe nativo
    if (typeof window !== "undefined" && ((window.matchMedia && window.matchMedia("(pointer: coarse)").matches) || (window.innerWidth || 1280) < 1024)) return;
    let down = false, startX = 0, scrollL = 0;
    const d = (e) => { down = true; startX = e.pageX - el.offsetLeft; scrollL = el.scrollLeft; el.classList.add("dragging"); };
    const m = (e) => { if (!down) return; e.preventDefault(); const x = e.pageX - el.offsetLeft; el.scrollLeft = scrollL - (x - startX); };
    const u = () => { down = false; el.classList.remove("dragging"); };
    el.addEventListener("mousedown", d);
    el.addEventListener("mousemove", m);
    el.addEventListener("mouseup", u);
    el.addEventListener("mouseleave", u);
    return () => {
      el.removeEventListener("mousedown", d);
      el.removeEventListener("mousemove", m);
      el.removeEventListener("mouseup", u);
      el.removeEventListener("mouseleave", u);
    };
  }, []);

  // Swipe-vs-tap disambiguation (mobile/tablet) — bloquea click si dedo se movio > 10px
  // Sin esto, touchend sobre .fcard dispara onClick y abre modal cancelando swipe.
  useEffectP(() => {
    const el = trackRef.current; if (!el) return;
    if (typeof window === "undefined") return;
    const isTouch = (window.matchMedia && window.matchMedia("(pointer: coarse)").matches) || (window.innerWidth || 1280) < 1024;
    if (!isTouch) return;
    const THRESHOLD = 10;
    let startX = 0, startY = 0, moved = false;
    const onStart = (e) => {
      const t = e.touches && e.touches[0]; if (!t) return;
      startX = t.clientX; startY = t.clientY; moved = false;
    };
    const onMove = (e) => {
      const t = e.touches && e.touches[0]; if (!t) return;
      if (Math.abs(t.clientX - startX) > THRESHOLD || Math.abs(t.clientY - startY) > THRESHOLD) moved = true;
    };
    const onClickCapture = (e) => {
      if (moved) { e.stopPropagation(); e.preventDefault(); }
    };
    el.addEventListener("touchstart", onStart, { passive: true });
    el.addEventListener("touchmove", onMove, { passive: true });
    el.addEventListener("click", onClickCapture, true);  // capture phase: intercepta antes del onClick de article
    return () => {
      el.removeEventListener("touchstart", onStart);
      el.removeEventListener("touchmove", onMove);
      el.removeEventListener("click", onClickCapture, true);
    };
  }, []);

  // Edge-hover auto-scroll (pausa inmediata en wheel vertical) — desktop only
  useEffectP(() => {
    const el = trackRef.current; if (!el) return;
    // Skip on touch devices: el edge-hover no aplica con dedo
    if (typeof window !== "undefined" && ((window.matchMedia && window.matchMedia("(pointer: coarse)").matches) || (window.innerWidth || 1280) < 1024)) return;
    const EDGE = 160;        // px desde borde que activa auto-scroll
    const MAX_SPEED = 2.5;   // px por frame al borde
    let speed = 0;
    let raf = 0;
    let hovering = false;
    let autoOn = false;

    const stopAuto = () => {
      speed = 0;
      if (autoOn) { el.classList.remove("auto-scrolling"); autoOn = false; }
      if (raf) { cancelAnimationFrame(raf); raf = 0; }
    };

    const tick = () => {
      if (!hovering || Math.abs(speed) < 0.05) {
        stopAuto();
        return;
      }
      if (!autoOn) { el.classList.add("auto-scrolling"); autoOn = true; }
      el.scrollLeft += speed;
      raf = requestAnimationFrame(tick);
    };

    const onMove = (e) => {
      if (el.classList.contains("dragging")) { speed = 0; return; }
      const rect = el.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const w = rect.width;
      if (x < EDGE) {
        const p = 1 - (x / EDGE);
        speed = -MAX_SPEED * Math.max(0, Math.min(1, p));
      } else if (x > w - EDGE) {
        const p = (x - (w - EDGE)) / EDGE;
        speed = MAX_SPEED * Math.max(0, Math.min(1, p));
      } else {
        speed = 0;
      }
      if (!raf && Math.abs(speed) > 0.05) {
        hovering = true;
        raf = requestAnimationFrame(tick);
      }
    };

    const onEnter = () => { hovering = true; };
    const onLeave = () => { hovering = false; stopAuto(); };

    // Wheel vertical sobre track → cancela rAF un frame (previene freeze con scroll-snap)
    // Siguiente mousemove reanuda edge-hover naturalmente. NO afecta wheel horizontal.
    const onWheel = (e) => {
      if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
        stopAuto();
      }
    };

    el.addEventListener("mouseenter", onEnter);
    el.addEventListener("mousemove", onMove);
    el.addEventListener("mouseleave", onLeave);
    el.addEventListener("wheel", onWheel, { passive: true });
    return () => {
      el.removeEventListener("mouseenter", onEnter);
      el.removeEventListener("mousemove", onMove);
      el.removeEventListener("mouseleave", onLeave);
      el.removeEventListener("wheel", onWheel);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  const goDot = (i) => {
    const el = trackRef.current; if (!el) return;
    const max = el.scrollWidth - el.clientWidth;
    el.scrollTo({ left: (max * i) / 4, behavior: "smooth" });
  };

  // Auto-rotate loop — lento, continuo, no bloquea scroll usuario
  // Velocidad adaptativa: mobile mas lento (cards pequenias), tablet medio, desktop normal
  useEffectP(() => {
    const el = trackRef.current; if (!el) return;
    // Touch/coarse-pointer devices: no auto-rotate, solo swipe nativo con dedo
    if (typeof window !== "undefined" && ((window.matchMedia && window.matchMedia("(pointer: coarse)").matches) || (window.innerWidth || 1280) < 1024)) return;
    const USER_PAUSE_MS = 3500;   // pausa tras interaccion usuario
    let raf = 0;
    let hovering = false;
    let lastUser = 0;
    let rotating = false;

    // Velocidad en px/segundo (independiente de frame rate). Adaptativa por viewport.
    // Mobile + tablet: auto-scroll desactivado — solo arrastre manual (touch/drag).
    const computeSpeedPxSec = () => {
      if (typeof window === "undefined") return 10;
      if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return 0;
      const w = window.innerWidth || 1280;
      if (w < 1024) return 0;   // mobile + tablet: sin auto-rotate, solo drag dedo
      if (w < 1440) return 14;  // laptop
      return 20;                // desktop grande
    };

    let SPEED_PX_SEC = computeSpeedPxSec();
    let accum = 0;       // float accumulator (scrollLeft se redondea a int al setear)
    let lastTime = 0;    // ms timestamp previo para delta time
    const onResize = () => { SPEED_PX_SEC = computeSpeedPxSec(); };
    window.addEventListener("resize", onResize, { passive: true });

    // Pausa cuando tab no visible (ahorra CPU, evita jump al volver)
    const onVisibility = () => { lastUser = Date.now(); };
    document.addEventListener("visibilitychange", onVisibility);

    const markUser = () => { lastUser = Date.now(); };

    const tick = (now) => {
      const dt = lastTime ? Math.min(now - lastTime, 100) : 16;  // cap dt a 100ms (tab bg)
      lastTime = now;

      if (SPEED_PX_SEC <= 0) { raf = requestAnimationFrame(tick); return; }
      // Pausa si: hover / drag / edge-hover / reciente accion usuario / tab oculta
      const paused = hovering
        || document.hidden
        || el.classList.contains("dragging")
        || el.classList.contains("auto-scrolling")
        || (Date.now() - lastUser < USER_PAUSE_MS);

      if (paused) {
        if (rotating) { el.classList.remove("auto-rotating"); rotating = false; }
        raf = requestAnimationFrame(tick);
        return;
      }

      const max = el.scrollWidth - el.clientWidth;
      if (max <= 0) { raf = requestAnimationFrame(tick); return; }

      if (!rotating) { el.classList.add("auto-rotating"); rotating = true; }

      // Sync accum con scroll real (usuario pudo haber movido)
      if (Math.abs(accum - el.scrollLeft) > 2) accum = el.scrollLeft;
      accum += SPEED_PX_SEC * (dt / 1000);  // time-based: frame-rate independent
      if (accum >= max - 0.5) accum = 0;    // wrap fin->inicio
      el.scrollLeft = accum;
      raf = requestAnimationFrame(tick);
    };

    const onEnter = () => { hovering = true; };
    const onLeave = () => { hovering = false; };

    el.addEventListener("mouseenter", onEnter);
    el.addEventListener("mouseleave", onLeave);
    el.addEventListener("wheel", markUser, { passive: true });
    el.addEventListener("touchstart", markUser, { passive: true });
    el.addEventListener("mousedown", markUser);
    el.addEventListener("keydown", markUser);

    raf = requestAnimationFrame(tick);
    return () => {
      cancelAnimationFrame(raf);
      if (rotating) el.classList.remove("auto-rotating");
      window.removeEventListener("resize", onResize);
      document.removeEventListener("visibilitychange", onVisibility);
      el.removeEventListener("mouseenter", onEnter);
      el.removeEventListener("mouseleave", onLeave);
      el.removeEventListener("wheel", markUser);
      el.removeEventListener("touchstart", markUser);
      el.removeEventListener("mousedown", markUser);
      el.removeEventListener("keydown", markUser);
    };
  }, [filtered.length]);

  // Title: split on last space for "Propiedades Destacadas" style
  const rawTitle = t.featured.title;
  const titleParts = rawTitle.split(" ");
  const titleLast = titleParts.pop();
  const titleHead = titleParts.join(" ");

  const chips = [
    { id: "all",        label: "Todos" },
    { id: "villa",      label: "Villas" },
    { id: "apartment",  label: "Apartamentos" },
    { id: "land",       label: "Terrenos" },
    { id: "commercial", label: "Comercial" },
    { id: "ultra",      label: "Ultra Lujo" },
  ];

  return (
    <section className="featured-v2" id="properties">
      <div className="container">
        <div className="featured-v2__head reveal">
          <h2 className="featured-v2__title">
            {titleHead} <em>{titleLast}</em>
          </h2>
          <button className="featured-v2__all"
            onClick={() => { if (onViewAll) onViewAll(); else location.hash = "#/propiedades"; }}>
            Ver todas <Icon.Arrow />
          </button>
        </div>

        <div className="featured-v2__chips reveal">
          {chips.map(c => (
            <button key={c.id}
              className={`featured-v2__chip${filter === c.id ? " active" : ""}`}
              onClick={() => setFilter(c.id)}>
              {c.label}
            </button>
          ))}
        </div>

        <div ref={trackRef} className="featured-v2__track">
          {filtered.map(p => (
            <FCard key={p.id} p={p} onOpen={onOpen}
              isFav={favorites.includes(p.id)} onFav={onFav}
              corner={cornerFor(p)} />
          ))}
        </div>

        <div className="featured-v2__dots">
          {[0,1,2,3,4].map(i => (
            <button key={i}
              className={`featured-v2__dot${activeDot === i ? " active" : ""}`}
              onClick={() => goDot(i)}
              aria-label={`Slide ${i+1}`} />
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// EDITORIAL GRID
// ============================================================
function EditorialGrid({ t, properties, onOpen, favorites, onFav, searchFilters }) {
  const [filter, setFilter] = useStateP("all");

  // Apply search + filter
  const filtered = useMemoP(() => {
    return properties.filter(p => {
      if (filter !== "all" && p.operation !== filter) return false;
      if (searchFilters) {
        if (searchFilters.op !== "any" && p.operation !== searchFilters.op) return false;
        if (searchFilters.type !== "any" && p.type !== searchFilters.type) return false;
        if (searchFilters.zone !== "any" && p.zone !== searchFilters.zone) return false;
        if (searchFilters.budget !== "any") {
          const [min, max] = BUDGET_RANGES[searchFilters.budget];
          const price = p.price || p.rent * 100;
          // Inclusive min, exclusive max; final bucket (Infinity) unbounded.
          if (price < min) return false;
          if (max !== Infinity && price >= max) return false;
        }
      }
      return true;
    });
  }, [properties, filter, searchFilters]);

  // Assign varied sizes cyclically
  const sizes = ["w5", "w4", "w6", "w3", "w4", "w5", "w7", "w5", "w4", "w3", "w5", "w4"];

  return (
    <section className="section" id="zones">
      <div className="container">
        <div className="section-head reveal">
          <div>
            <span className="eyebrow">{t.editorial.eyebrow}</span>
            <h2>{t.editorial.title}</h2>
          </div>
          <p>{t.editorial.sub}</p>
        </div>

        <div className="editorial__filters reveal">
          <button className={`editorial__filter${filter === "all" ? " active" : ""}`} onClick={() => setFilter("all")}>{t.editorial.filterAll}</button>
          <button className={`editorial__filter${filter === "sale" ? " active" : ""}`} onClick={() => setFilter("sale")}>{t.editorial.filterSale}</button>
          <button className={`editorial__filter${filter === "rent" ? " active" : ""}`} onClick={() => setFilter("rent")}>{t.editorial.filterRent}</button>
          <button className={`editorial__filter${filter === "vacation" ? " active" : ""}`} onClick={() => setFilter("vacation")}>{t.editorial.filterVacation}</button>
        </div>

        <div className="editorial__grid">
          {filtered.map((p, i) => (
            <GCard key={p.id} p={p} t={t} size={sizes[i % sizes.length]}
              onOpen={onOpen} isFav={favorites.includes(p.id)} onFav={onFav} />
          ))}
        </div>
      </div>
    </section>
  );
}

function GCard({ p, t, size, onOpen, isFav, onFav }) {
  return (
    <div className={`gcard gcard--${size} reveal`} onClick={() => onOpen(p)}>
      <div className="gcard__img">
        <img src={p.images[0]} alt={p.name} loading="lazy" />
        <button className="pcard__fav" onClick={(e) => { e.stopPropagation(); onFav(p.id); }} style={{ top: 14, right: 14, position: "absolute" }}>
          <Icon.Heart fill={isFav ? "currentColor" : "none"} />
        </button>
      </div>
      <div className="gcard__info">
        <div>
          <h4>{p.name}</h4>
          <p>{[p.zone, p.city].filter(Boolean).join(" · ")}</p>
          <div className="gcard__price" style={{ marginTop: 6 }}>
            {p.price ? formatPrice(p.price) : formatRent(p.rent)}
          </div>
        </div>
        <span className="gcard__op">
          {p.operation === "sale" ? t.editorial.sale : p.operation === "rent" ? t.editorial.rent : t.editorial.vacation}
        </span>
      </div>
    </div>
  );
}

// ============================================================
// PILLARS
// ============================================================
function Pillars({ t }) {
  return (
    <section className="pillars" id="pillars">
      <div className="container">
        <div className="section-head reveal" style={{ marginBottom: 60 }}>
          <div>
            <span className="eyebrow">{t.pillars.eyebrow}</span>
            <h2>{t.pillars.title}</h2>
          </div>
        </div>
        <div className="pillars__grid">
          {[
            { t: t.pillars.p1t, d: t.pillars.p1d },
            { t: t.pillars.p2t, d: t.pillars.p2d },
            { t: t.pillars.p3t, d: t.pillars.p3d },
            { t: t.pillars.p4t, d: t.pillars.p4d },
          ].map((item, i) => (
            <div key={i} className="pillar reveal">
              <div className="pillar__num">{String(i + 1).padStart(2, "0")}</div>
              <h3 className="pillar__title">{item.t}</h3>
              <p className="pillar__desc">{item.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// PROCESS
// ============================================================
function Process({ t }) {
  const [active, setActive] = useStateP(0);
  const sectionRef = useRefP(null);

  useEffectP(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          // Animate each step in sequence
          [0, 1, 2, 3].forEach((i) => {
            setTimeout(() => setActive(i + 1), 300 + i * 400);
          });
          io.disconnect();
        }
      });
    }, { threshold: 0.3 });
    if (sectionRef.current) io.observe(sectionRef.current);
    return () => io.disconnect();
  }, []);

  const steps = [
    { t: t.process.s1t, d: t.process.s1d },
    { t: t.process.s2t, d: t.process.s2d },
    { t: t.process.s3t, d: t.process.s3d },
    { t: t.process.s4t, d: t.process.s4d },
  ];

  return (
    <section className="process" id="process" ref={sectionRef}>
      <div className="container">
        <div className="section-head reveal">
          <div>
            <span className="eyebrow">{t.process.eyebrow}</span>
            <h2>{t.process.title}</h2>
          </div>
        </div>
        <div className="process__steps">
          <div className="process__line"></div>
          <div className="process__line-fill" style={{ width: `${(active / 4) * 100}%` }}></div>
          {steps.map((step, i) => (
            <div key={i} className={`pstep reveal${active > i ? " active" : ""}`}>
              <div className="pstep__num">{String(i + 1).padStart(2, "0")}</div>
              <h3 className="pstep__title">{step.t}</h3>
              <p className="pstep__desc">{step.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// SELL BANNER
// ============================================================
function SellBanner({ t }) {
  const bgRef = useRefP(null);
  useEffectP(() => {
    const onScroll = () => {
      if (!bgRef.current) return;
      const rect = bgRef.current.parentElement.getBoundingClientRect();
      const centerOffset = rect.top + rect.height / 2 - window.innerHeight / 2;
      bgRef.current.style.transform = `translateY(${centerOffset * -0.08}px) scale(1.08)`;
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <section className="sell-banner" id="sell">
      <div className="sell-banner__content">
        <div ref={bgRef} className="sell-banner__bg">
          <img src="https://images.pexels.com/photos/1732414/pexels-photo-1732414.jpeg?auto=compress&cs=tinysrgb&w=2400" alt="" />
        </div>
        <div className="sell-banner__panel reveal">
          <h2 className="sell-banner__title">{t.sell.title}</h2>
          <p className="sell-banner__sub">{t.sell.sub}</p>
          <div className="sell-banner__meta">
            <div className="sell-banner__meta-item">
              <span className="sell-banner__meta-val">24–48h</span>
              <span className="sell-banner__meta-lbl">Respuesta</span>
            </div>
            <div className="sell-banner__meta-item">
              <span className="sell-banner__meta-val">100%</span>
              <span className="sell-banner__meta-lbl">Confidencial</span>
            </div>
            <div className="sell-banner__meta-item">
              <span className="sell-banner__meta-val">0 USD</span>
              <span className="sell-banner__meta-lbl">Valuación</span>
            </div>
          </div>
          <div className="sell-banner__cta-row">
            <a href="#/vender" className="btn-gold" onClick={(e) => { e.preventDefault(); location.hash = "#/vender"; }}>
              {t.sell.cta}
              <span className="arrow"><Icon.Arrow /></span>
            </a>
            <span className="sell-banner__cta-note">Sin exposición pública</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// MAP
// ============================================================
function MapSection({ t, properties, onCity }) {
  const mapRef = useRefP(null);
  const [activeCity, setActiveCity] = useStateP(null);

  useEffectP(() => {
    if (!mapRef.current || !window.L) return;
    if (mapRef.current._leaflet_id) return;
    const map = window.L.map(mapRef.current, {
      center: [19.79, -70.69],
      zoom: 10,
      scrollWheelZoom: false,
      zoomControl: true,
      attributionControl: true,
    });

    // Wheel zoom solo cuando mouse sobre mapa
    const mapEl = mapRef.current;
    const onEnter = () => map.scrollWheelZoom.enable();
    const onLeave = () => map.scrollWheelZoom.disable();
    mapEl.addEventListener("mouseenter", onEnter);
    mapEl.addEventListener("mouseleave", onLeave);
    window.L.tileLayer("https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", {
      attribution: "© OpenStreetMap · CARTO",
      maxZoom: 18,
    }).addTo(map);

    // Add markers for properties
    properties.forEach(p => {
      const icon = window.L.divIcon({
        className: "lgm-marker",
        html: `<div style="width:16px;height:16px;background:#c9a876;border:2px solid #fff;border-radius:50%;box-shadow:0 0 0 2px #c9a876, 0 4px 12px rgba(0,0,0,0.4);"></div>`,
        iconSize: [20, 20],
        iconAnchor: [10, 10],
      });
      const marker = window.L.marker(p.coords, { icon }).addTo(map);
      marker.bindPopup(`<div style="font-family:var(--f-display); padding:4px 0;"><strong style="font-size:16px;">${p.name}</strong><br/><span style="font-size:12px;color:#a89f8a;">${p.zone}</span><br/><span style="color:#c9a876;font-size:14px;">${p.price ? formatPrice(p.price) : formatRent(p.rent)}</span></div>`);
    });

    // Save reference for city fly-to
    window.__lgmMap = map;
  }, [properties]);

  const zones = window.LGM_ZONES;

  const cityCoords = {
    "Puerto Plata (Capital)": [19.7920, -70.6880],
    "Sosúa": [19.7550, -70.5150],
    "Cabarete": [19.7580, -70.4150],
    "Montellano": [19.7470, -70.6020],
    "Imbert": [19.7470, -70.8300],
    "Luperón": [19.9020, -70.9500],
    "Altamira": [19.7020, -70.8370],
    "Guananico": [19.7100, -70.9050],
    "Los Hidalgos": [19.7180, -70.9820],
    "Villa Isabela": [19.8870, -71.0730],
    "Villa Montellano": [19.7540, -70.5780],
  };

  const flyTo = (city) => {
    setActiveCity(city);
    const c = cityCoords[city];
    if (c && window.__lgmMap) window.__lgmMap.flyTo(c, 12, { duration: 1.2 });
  };

  const propertyCounts = useMemoP(() => {
    const counts = {};
    properties.forEach(p => { counts[p.city] = (counts[p.city] || 0) + 1; });
    return counts;
  }, [properties]);

  return (
    <section className="map-section" id="map">
      <div className="section-head reveal" style={{ maxWidth: "var(--container)", margin: "0 auto 80px" }}>
        <div>
          <span className="eyebrow">{t.map.eyebrow}</span>
          <h2>{t.map.title}</h2>
        </div>
        <p>{t.map.sub}</p>
      </div>
      <div className="map-wrap">
        <div className="map-container reveal">
          <div ref={mapRef} id="leaflet-map"></div>
        </div>
        <aside className="map-legend reveal">
          <h4 style={{ color: "var(--gold)" }}>Puerto Plata</h4>
          {zones.map(z => (
            <div key={z.city} className="map-legend__city" onClick={() => flyTo(z.city)}
              style={{ color: activeCity === z.city ? "var(--gold)" : undefined }}>
              <div className="map-legend__city-name">
                <span>{z.city}</span>
                <span className="map-legend__count">
                  {String(propertyCounts[z.city] || 0).padStart(2, "0")} / {String(z.areas.length).padStart(2, "0")}
                </span>
              </div>
            </div>
          ))}
        </aside>
      </div>
    </section>
  );
}

Object.assign(window, { PCard, FCard, FeaturedCarousel, EditorialGrid, GCard, Pillars, Process, SellBanner, MapSection });
