// ============================================================
// LGM — Páginas (Home, Propiedades, Sobre mí, Servicios) + Router
// ============================================================
const { useState: uSp, useEffect: uEp, useRef: uRp, useMemo: uMp } = React;

// --------- HASH ROUTER ---------
function useRoute() {
  const parse = () => {
    // Hash route first; fallback a pathname para deep links (/vender, /propiedades, etc.)
    const hash = (location.hash || "").replace(/^#/, "");
    const source = hash || (location.pathname && location.pathname !== "/" ? location.pathname : "/");
    const [path, query] = source.split("?");
    return { path: path || "/", query: new URLSearchParams(query || "") };
  };
  const [route, setRoute] = uSp(parse);
  uEp(() => {
    const on = () => {
      setRoute(parse());
      window.scrollTo({ top: 0, behavior: "instant" });
    };
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  const go = (to) => { location.hash = to.startsWith("#") ? to : "#" + to; };
  return { route, go };
}

// --------- PAGE TRANSITION WRAPPER ---------
// Keyed remount + CSS enter animation. Children rerender normally within a stable route.
function PageTransition({ routeKey, children }) {
  return (
    <div className="page-transition page-transition--in" key={routeKey}>
      {children}
    </div>
  );
}

// ============================================================
// HOME (adelgazada: hero + carrusel + mapa + sell banner)
// ============================================================
function HomePage({ t, onSearch, onOpen, favorites, onFav, allProps, featured }) {
  return (
    <>
      <Hero t={t} onSearch={onSearch} allProps={allProps} />
      <Ticker t={t} />
      <FeaturedCarousel t={t} properties={featured} onOpen={onOpen}
        favorites={favorites} onFav={onFav} />
      <MapSection t={t} properties={allProps} />
      <SellBanner t={t} />
    </>
  );
}

// ============================================================
// PROPIEDADES (listado completo + filtros avanzados)
// ============================================================
function PropertiesPage({ t, allProps, onOpen, favorites, onFav, initialFilters }) {
  const [filters, setFilters] = uSp(() => ({
    op: "any", type: "any", province: "any", city: "any", zone: "any", budget: "any",
    beds: 0, baths: 0, parking: 0,
    q: "",
    sort: "featured",
    amenities: [],
    ...(initialFilters || {}),
  }));
  const [view, setView] = uSp("grid"); // grid | list
  const [amenOpen, setAmenOpen] = uSp(false);

  const toggleAmen = (slug) => {
    setFilters(f => {
      const cur = Array.isArray(f.amenities) ? f.amenities : [];
      return { ...f, amenities: cur.includes(slug) ? cur.filter(x => x !== slug) : [...cur, slug] };
    });
  };

  const filtered = uMp(() => {
    const reqAmen = Array.isArray(filters.amenities) ? filters.amenities : [];
    let list = allProps.filter(p => {
      if (filters.op !== "any" && p.operation !== filters.op) return false;
      if (filters.type !== "any" && p.type !== filters.type) return false;
      if (filters.province !== "any" && p.province !== filters.province) return false;
      if (filters.city !== "any" && p.city !== filters.city) return false;
      if (filters.zone !== "any" && p.zone !== filters.zone) return false;
      if (filters.beds > 0 && p.beds < filters.beds) return false;
      if (filters.baths > 0 && p.baths < filters.baths) return false;
      if (filters.parking > 0 && p.parking < filters.parking) return false;
      if (filters.budget !== "any") {
        const [min, max] = BUDGET_RANGES[filters.budget];
        const price = p.price || (p.rent ? p.rent * 100 : 0);
        // Inclusive min, exclusive max; final bucket (Infinity) unbounded.
        if (price < min) return false;
        if (max !== Infinity && price >= max) return false;
      }
      if (reqAmen.length) {
        const pa = Array.isArray(p.amenities) ? p.amenities : [];
        for (const s of reqAmen) if (!pa.includes(s)) return false;
      }
      if (filters.q.trim()) {
        const q = filters.q.trim().toLowerCase();
        const hay = `${p.name} ${p.zone} ${p.city} ${p.type} ${p.ref} ${(p.features||[]).join(" ")}`.toLowerCase();
        if (!hay.includes(q)) return false;
      }
      return true;
    });
    const s = filters.sort;
    list = [...list].sort((a, b) => {
      if (s === "priceAsc") return (a.price || a.rent*100) - (b.price || b.rent*100);
      if (s === "priceDesc") return (b.price || b.rent*100) - (a.price || a.rent*100);
      if (s === "bedsDesc") return b.beds - a.beds;
      if (s === "areaDesc") return b.area - a.area;
      if (s === "newest") return b.year - a.year;
      return (b.featured ? 1 : 0) - (a.featured ? 1 : 0);
    });
    return list;
  }, [allProps, filters]);

  // Count properties per filter value → hide options with count = 0
  const counts = uMp(() => {
    const c = { op: {}, type: {}, province: {}, city: {}, zone: {}, beds: {}, baths: {}, parking: {}, budget: {} };
    for (const p of allProps) {
      if (p.operation) c.op[p.operation] = (c.op[p.operation] || 0) + 1;
      if (p.type) c.type[p.type] = (c.type[p.type] || 0) + 1;
      if (p.province) c.province[p.province] = (c.province[p.province] || 0) + 1;
      if (p.city) c.city[p.city] = (c.city[p.city] || 0) + 1;
      if (p.zone) c.zone[p.zone] = (c.zone[p.zone] || 0) + 1;
      // Budget buckets (inclusive min, exclusive max; last bucket = Infinity catches all ≥ min)
      const price = p.price || (p.rent ? p.rent * 100 : 0);
      for (const [k, [min, max]] of Object.entries(BUDGET_RANGES)) {
        if (k === "any") continue;
        const inRange = max === Infinity ? price >= min : price >= min && price < max;
        if (inRange) c.budget[k] = (c.budget[k] || 0) + 1;
      }
    }
    return c;
  }, [allProps]);

  // Índice de ubicaciones derivado de propiedades reales (no listas estáticas):
  // provinciasConProps → cities → zones. Solo aparece lo que realmente existe.
  const locIndex = uMp(() => {
    const provMap = {};   // province → Set<city>
    const cityMap = {};   // city → Set<zone>
    const cityProv = {};  // city → province
    for (const p of allProps) {
      if (p.province) {
        (provMap[p.province] = provMap[p.province] || new Set());
        if (p.city) provMap[p.province].add(p.city);
      }
      if (p.city) {
        (cityMap[p.city] = cityMap[p.city] || new Set());
        if (p.zone) cityMap[p.city].add(p.zone);
        if (p.province) cityProv[p.city] = p.province;
      }
    }
    return { provMap, cityMap, cityProv };
  }, [allProps]);

  const opOptions = uMp(() => {
    const all = [
      { v: "sale", l: t.ops.sale },
      { v: "rent", l: t.ops.rent },
      { v: "vacation", l: t.ops.vacation },
    ].filter(o => (counts.op[o.v] || 0) > 0);
    return [{ v: "any", l: t.ops.any }, ...all];
  }, [counts, t]);

  const typeOptions = uMp(() => {
    const all = [
      { v: "villa", l: t.types.villa },
      { v: "apartment", l: t.types.apartment },
      { v: "penthouse", l: t.types.penthouse },
      { v: "house", l: t.types.house },
      { v: "land", l: t.types.land },
      { v: "commercial", l: t.types.commercial },
    ].filter(o => (counts.type[o.v] || 0) > 0);
    return [{ v: "any", l: t.types.any }, ...all];
  }, [counts, t]);

  const budgetOptions = uMp(() => {
    const all = [
      { value: "b1", label: t.budget.b1 },
      { value: "b2", label: t.budget.b2 },
      { value: "b3", label: t.budget.b3 },
      { value: "b4", label: t.budget.b4 },
      { value: "b5", label: t.budget.b5 },
    ].filter(o => (counts.budget[o.value] || 0) > 0);
    return [{ value: "any", label: t.budget.any }, ...all];
  }, [counts, t]);

  // Provincias con al menos 1 propiedad
  const provinces = uMp(() => {
    return Object.keys(locIndex.provMap).sort((a, b) => a.localeCompare(b));
  }, [locIndex]);

  // Ciudades: si provincia seleccionada → solo sus municipios con props;
  // si "any" → todas las ciudades con props
  const cities = uMp(() => {
    if (filters.province !== "any") {
      const set = locIndex.provMap[filters.province];
      return set ? Array.from(set).sort((a, b) => a.localeCompare(b)) : [];
    }
    const set = new Set(allProps.map(p => p.city).filter(Boolean));
    return Array.from(set).sort((a, b) => a.localeCompare(b));
  }, [allProps, filters.province, locIndex]);

  // Zonas: si ciudad → solo zonas de esa ciudad con props;
  // si provincia (sin city) → todas las zonas de municipios en esa provincia;
  // si "any" → todas las zonas con props
  const currentCityZones = uMp(() => {
    if (filters.city !== "any") {
      const set = locIndex.cityMap[filters.city];
      return set ? Array.from(set).sort((a, b) => a.localeCompare(b)) : [];
    }
    if (filters.province !== "any") {
      const citySet = locIndex.provMap[filters.province];
      if (!citySet) return [];
      const zoneSet = new Set();
      citySet.forEach(c => {
        const zs = locIndex.cityMap[c];
        if (zs) zs.forEach(z => zoneSet.add(z));
      });
      return Array.from(zoneSet).sort((a, b) => a.localeCompare(b));
    }
    return Object.keys(counts.zone).sort((a, b) => a.localeCompare(b));
  }, [filters.province, filters.city, locIndex, counts]);

  const reset = () => setFilters({
    op: "any", type: "any", province: "any", city: "any", zone: "any", budget: "any",
    beds: 0, baths: 0, parking: 0, q: "", sort: "featured", amenities: [],
  });

  const amenCatalog = window.LGM_AMENITIES || { categories: [], items: [] };
  const amenLabels = (t && t.amenities) || {};
  const amenCatLabels = amenLabels._categories || {};

  return (
    <section className="page page--props">
      <div className="container page__body">
        {/* Filtros avanzados */}
        <aside className="filters">
          <div className="filters__head">
            <h3>{t.propsPage?.filters || "Filtros"}</h3>
            <button className="filters__reset" onClick={reset}>
              {t.propsPage?.reset || "Limpiar"}
            </button>
          </div>

          <div className="filters__search">
            <Icon.Search />
            <input type="text" placeholder={t.propsPage?.search || "Buscar por nombre, zona, ref..."}
              value={filters.q}
              onChange={e => setFilters(f => ({ ...f, q: e.target.value }))} />
          </div>

          {opOptions.length > 1 && (
            <FilterGroup label={t.hero.searchOp}>
              <FilterPills value={filters.op} onChange={v => setFilters(f => ({ ...f, op: v }))}
                options={opOptions} />
            </FilterGroup>
          )}

          {typeOptions.length > 1 && (
            <FilterGroup label={t.hero.searchType}>
              <FilterPills value={filters.type} onChange={v => setFilters(f => ({ ...f, type: v }))}
                options={typeOptions} />
            </FilterGroup>
          )}

          {provinces.length > 0 && (
            <FilterGroup label={t.propsPage?.province || "Provincia"}>
              <Dropdown variant="filter" ariaLabel={t.propsPage?.province || "Provincia"}
                value={filters.province}
                onChange={e => setFilters(f => ({ ...f, province: e.target.value, city: "any", zone: "any" }))}
                options={[
                  { value: "any", label: t.types.any },
                  ...provinces.map(p => ({ value: p, label: p })),
                ]} />
            </FilterGroup>
          )}

          {cities.length > 0 && (
            <FilterGroup label={t.propsPage?.city || "Ciudad"}>
              <Dropdown variant="filter" ariaLabel={t.propsPage?.city || "Ciudad"}
                value={filters.city}
                onChange={e => setFilters(f => ({ ...f, city: e.target.value, zone: "any" }))}
                options={[
                  { value: "any", label: t.types.any },
                  ...cities.map(c => ({ value: c, label: c })),
                ]} />
            </FilterGroup>
          )}

          {currentCityZones.length > 0 && (
            <FilterGroup label={t.propsPage?.zone || "Zona / Sector"}>
              <Dropdown variant="filter" ariaLabel={t.propsPage?.zone || "Zona / Sector"}
                value={filters.zone}
                onChange={e => setFilters(f => ({ ...f, zone: e.target.value }))}
                options={[
                  { value: "any", label: t.types.any },
                  ...currentCityZones.map(z => ({ value: z, label: z })),
                ]} />
            </FilterGroup>
          )}

          {budgetOptions.length > 1 && (
            <FilterGroup label={t.hero.searchBudget}>
              <Dropdown variant="filter" ariaLabel={t.hero.searchBudget}
                value={filters.budget}
                onChange={e => setFilters(f => ({ ...f, budget: e.target.value }))}
                options={budgetOptions} />
            </FilterGroup>
          )}

          <FilterGroup label={t.prop.beds + " mín."}>
            <FilterPills value={filters.beds} onChange={v => setFilters(f => ({ ...f, beds: v }))}
              options={[0,1,2,3,4,5].map(n => ({ v: n, l: n === 0 ? "—" : `${n}+` }))} />
          </FilterGroup>

          <FilterGroup label={t.prop.baths + " mín."}>
            <FilterPills value={filters.baths} onChange={v => setFilters(f => ({ ...f, baths: v }))}
              options={[0,1,2,3,4].map(n => ({ v: n, l: n === 0 ? "—" : `${n}+` }))} />
          </FilterGroup>

          <FilterGroup label={t.prop.parking + " mín."}>
            <FilterPills value={filters.parking} onChange={v => setFilters(f => ({ ...f, parking: v }))}
              options={[0,1,2,3].map(n => ({ v: n, l: n === 0 ? "—" : `${n}+` }))} />
          </FilterGroup>

          {/* Amenities */}
          <div className="filter-group">
            <button type="button" className="filter-amen__head" onClick={() => setAmenOpen(o => !o)}>
              <span>{amenLabels._title || "Amenities"}{filters.amenities.length > 0 && (
                <span className="filter-amen__count">{filters.amenities.length}</span>
              )}</span>
              <span className={`filter-amen__chev${amenOpen ? " open" : ""}`}>▾</span>
            </button>
            {amenOpen && (
              <div className="filter-amen__body">
                {amenCatalog.categories.map(cat => {
                  const items = amenCatalog.items.filter(a => a.category === cat.key);
                  if (!items.length) return null;
                  return (
                    <div key={cat.key} className="filter-amen__group">
                      <div className="filter-amen__group-label">{amenCatLabels[cat.key] || cat.key}</div>
                      <div className="filter-amen__chips">
                        {items.map(a => {
                          const on = filters.amenities.includes(a.slug);
                          return (
                            <button key={a.slug} type="button"
                              className={`filter-amen__chip${on ? " on" : ""}`}
                              onClick={() => toggleAmen(a.slug)}>
                              {amenLabels[a.slug] || a.slug}
                            </button>
                          );
                        })}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        </aside>

        {/* Results */}
        <div className="results">
          <div className="results__head">
            <div className="results__count">
              <strong>{String(filtered.length).padStart(2, "0")}</strong>
              <span>{t.propsPage?.found || "propiedades encontradas"}</span>
            </div>
            <div className="results__controls">
              <Dropdown variant="sort" ariaLabel="Ordenar"
                value={filters.sort}
                onChange={e => setFilters(f => ({ ...f, sort: e.target.value }))}
                options={[
                  { value: "featured", label: t.propsPage?.sortFeatured || "Destacadas" },
                  { value: "priceAsc", label: t.propsPage?.sortPriceAsc || "Precio: menor → mayor" },
                  { value: "priceDesc", label: t.propsPage?.sortPriceDesc || "Precio: mayor → menor" },
                  { value: "bedsDesc", label: t.propsPage?.sortBedsDesc || "Más habitaciones" },
                  { value: "newest", label: t.propsPage?.sortNewest || "Más recientes" },
                ]} />
              <div className="results__view">
                <button className={view === "grid" ? "active" : ""} onClick={() => setView("grid")}
                  aria-label="Grid view">
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.4"><rect x="1" y="1" width="5" height="5"/><rect x="8" y="1" width="5" height="5"/><rect x="1" y="8" width="5" height="5"/><rect x="8" y="8" width="5" height="5"/></svg>
                </button>
                <button className={view === "list" ? "active" : ""} onClick={() => setView("list")}
                  aria-label="List view">
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.4"><line x1="1" y1="3" x2="13" y2="3"/><line x1="1" y1="7" x2="13" y2="7"/><line x1="1" y1="11" x2="13" y2="11"/></svg>
                </button>
              </div>
            </div>
          </div>

          {filtered.length === 0 ? (
            <div className="results__empty">
              <p>{t.propsPage?.empty || "No hay propiedades que coincidan con los filtros."}</p>
              <button className="btn-ghost" onClick={reset}>{t.propsPage?.reset || "Limpiar filtros"}</button>
            </div>
          ) : view === "grid" ? (
            <div className="results__grid">
              {filtered.map(p => (
                <PCard key={p.id} p={p} t={t} onOpen={onOpen}
                  isFav={favorites.includes(p.id)} onFav={onFav} />
              ))}
            </div>
          ) : (
            <div className="results__list">
              {filtered.map(p => (
                <ListCard key={p.id} p={p} t={t} onOpen={onOpen}
                  isFav={favorites.includes(p.id)} onFav={onFav} />
              ))}
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

function FilterGroup({ label, children }) {
  return (
    <div className="filter-group">
      <div className="filter-group__label">{label}</div>
      {children}
    </div>
  );
}

function FilterPills({ value, onChange, options }) {
  return (
    <div className="filter-pills">
      {options.map(o => (
        <button key={String(o.v)} className={`filter-pill${value === o.v ? " active" : ""}`}
          onClick={() => onChange(o.v)}>{o.l}</button>
      ))}
    </div>
  );
}

function ListCard({ p, t, onOpen, isFav, onFav }) {
  return (
    <article className="lcard" onClick={() => onOpen(p)}>
      <div className="lcard__img">
        <img src={p.images[0]} alt={p.name} loading="lazy" />
        <button className={`pcard__fav${isFav ? " active" : ""}`}
          onClick={(e) => { e.stopPropagation(); onFav(p.id); }}>
          <Icon.Heart fill={isFav ? "currentColor" : "none"} />
        </button>
      </div>
      <div className="lcard__body">
        <div>
          <div className="lcard__ref">{[`${t.prop.ref} ${p.ref}`, p.zone, p.city].filter(Boolean).join(" · ")}</div>
          <h3 className="lcard__name">{p.name}</h3>
          <p className="lcard__desc">{p.description}</p>
          <div className="lcard__specs">
            <div><Icon.Bed /> {p.beds} {t.prop.beds}</div>
            <div><Icon.Bath /> {p.baths} {t.prop.baths}</div>
            <div><Icon.Car /> {p.parking}</div>
            <div><Icon.Area /> {p.area}m²</div>
          </div>
        </div>
        <div className="lcard__aside">
          <span className="lcard__op">
            {p.operation === "sale" ? t.editorial.sale : p.operation === "rent" ? t.editorial.rent : t.editorial.vacation}
          </span>
          <div className="lcard__price">
            {p.price && <span className="lcard__price-main">{formatPrice(p.price)}</span>}
            {p.rent && <span className="lcard__price-alt">{formatRent(p.rent)}</span>}
          </div>
          <span className="btn-text lcard__cta">{t.prop.viewMore}<Icon.Arrow /></span>
        </div>
      </div>
    </article>
  );
}

// ============================================================
// SOBRE MÍ
// ============================================================
function AboutPage({ t }) {
  const stats = [
    { n: "12+", l: t.hero.metaYears || "Años de experiencia" },
    { n: "140+", l: t.hero.metaDeals || "Propiedades cerradas" },
    { n: "40+", l: t.hero.metaZones || "Zonas cubiertas" },
    { n: "6", l: t.aboutPage?.languages || "Idiomas" },
  ];

  return (
    <section className="page page--about">
      <div className="about__hero">
        <div className="about__hero-img">
          <img src="assets/luis-portrait.jpg" alt="Luis García Márquez" />
        </div>
        <div className="about__hero-content">
          <span className="eyebrow reveal-text">{t.nav.about}</span>
          <h1 className="page__title reveal-text">
            Luis <em>García</em> Márquez
          </h1>
          <p className="about__lede reveal-text">
            {t.aboutPage?.lede || "Más de una década conectando compradores internacionales con las residencias más excepcionales del norte dominicano. Discreción, rigor y conocimiento local profundo."}
          </p>
          <div className="about__meta reveal-text">
            <div><strong>Puerto Plata</strong><span>Base de operaciones</span></div>
            <div><strong>2014</strong><span>{t.aboutPage?.founded || "Fundación LGM"}</span></div>
            <div><strong>ES · EN · FR</strong><span>{t.aboutPage?.fluent || "Idiomas fluidos"}</span></div>
          </div>
        </div>
      </div>

      <div className="container about__body">
        <div className="about__grid">
          <div className="reveal">
            <span className="eyebrow">—— {t.aboutPage?.story || "Trayectoria"}</span>
            <h2 className="about__h2">{t.aboutPage?.storyTitle || "Del Caribe al mundo."}</h2>
          </div>
          <div className="about__prose reveal">
            <p>{t.aboutPage?.p1 || "Nacido y criado en Puerto Plata, Luis García Márquez combina el conocimiento íntimo de la tierra dominicana con una formación internacional en real estate de lujo. Licenciado en Administración, con certificaciones en la Dominican Republic Real Estate Association y formación en gestión patrimonial en Miami."}</p>
            <p>{t.aboutPage?.p2 || "Desde 2014, ha acompañado a más de 140 compradores — norteamericanos, europeos, caribeños — en la adquisición de villas, penthouses y estates en la costa norte. Su enfoque: menos volumen, mayor curaduría. Trabaja con un número limitado de clientes al año para garantizar atención completamente personalizada."}</p>
            <p>{t.aboutPage?.p3 || "La filosofía LGM es simple: cada propiedad pasa un filtro riguroso de título y deslinde antes de entrar en portafolio. Cada cliente recibe acompañamiento integral — legal, fiscal, de mantenimiento. El cierre es solo el comienzo de la relación."}</p>
          </div>
        </div>

        <div className="about__stats reveal">
          {stats.map(s => (
            <div key={s.l} className="about__stat">
              <strong>{s.n}</strong>
              <span>{s.l}</span>
            </div>
          ))}
        </div>

        <div className="about__grid">
          <div className="reveal">
            <span className="eyebrow">—— {t.aboutPage?.values || "Valores"}</span>
            <h2 className="about__h2">{t.aboutPage?.valuesTitle || "Principios no negociables."}</h2>
          </div>
          <div className="about__values reveal">
            {[
              { t: t.aboutPage?.v1t || "Discreción absoluta", d: t.aboutPage?.v1d || "Cada conversación, cada cifra, cada identidad se trata con confidencialidad total. Trabajamos con NDAs cuando la operación lo requiere." },
              { t: t.aboutPage?.v2t || "Título y deslinde", d: t.aboutPage?.v2d || "Ninguna propiedad entra en portafolio sin título certificado y deslinde aprobado por Tribunal de Tierras. Sin excepciones." },
              { t: t.aboutPage?.v3t || "Curaduría antes que volumen", d: t.aboutPage?.v3d || "Preferimos cerrar 15 operaciones al año con el cliente correcto, que 80 con cualquiera. La calidad de la relación es el indicador." },
              { t: t.aboutPage?.v4t || "Acompañamiento post-cierre", d: t.aboutPage?.v4d || "El día de las llaves no es el final. Mantenimiento, impuestos, gestión de inquilinos: continuamos a su lado." },
            ].map(v => (
              <div key={v.t} className="about__value">
                <h4>{v.t}</h4>
                <p>{v.d}</p>
              </div>
            ))}
          </div>
        </div>

        <div className="about__quote reveal">
          <blockquote>
            <p>"{t.aboutPage?.quote || "Una propiedad de lujo no se vende, se presenta. Mi trabajo es ser el puente discreto entre quien busca algo excepcional y el Caribe dominicano real — el que no aparece en folletos turísticos."}"</p>
            <footer>— Luis García Márquez</footer>
          </blockquote>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// SERVICIOS
// ============================================================
function ServicesPage({ t }) {
  const services = [
    {
      k: "buy",
      interestIdx: 0,
      eyebrow: "01",
      title: t.servicesPage?.s1t || "Compra de propiedad",
      sub: t.servicesPage?.s1s || "Para compradores internacionales que buscan una segunda residencia, una inversión o un retiro caribeño.",
      img: "https://images.pexels.com/photos/1438834/pexels-photo-1438834.jpeg?auto=compress&cs=tinysrgb&w=1600",
      items: [
        t.servicesPage?.s1i1 || "Briefing confidencial de necesidades",
        t.servicesPage?.s1i2 || "Selección curada de 4-6 propiedades verificadas",
        t.servicesPage?.s1i3 || "Tours presenciales o virtuales con drone",
        t.servicesPage?.s1i4 || "Due diligence legal y fiscal completa",
        t.servicesPage?.s1i5 || "Negociación directa con vendedor",
        t.servicesPage?.s1i6 || "Escrituración y registro en Tribunal de Tierras",
      ],
    },
    {
      k: "sell",
      interestIdx: 1,
      eyebrow: "02",
      title: t.servicesPage?.s2t || "Venta de propiedad",
      sub: t.servicesPage?.s2s || "Para propietarios que quieren vender discretamente al precio correcto, sin exposición masiva.",
      img: "https://images.pexels.com/photos/2462016/pexels-photo-2462016.jpeg?auto=compress&cs=tinysrgb&w=1600",
      items: [
        t.servicesPage?.s2i1 || "Valuación profesional basada en comparables reales",
        t.servicesPage?.s2i2 || "Fotografía editorial y video con drone",
        t.servicesPage?.s2i3 || "Verificación de título y deslinde",
        t.servicesPage?.s2i4 || "Marketing internacional segmentado",
        t.servicesPage?.s2i5 || "Calificación de compradores antes de visitas",
        t.servicesPage?.s2i6 || "Acompañamiento hasta cierre y entrega",
      ],
    },
    {
      k: "rent",
      interestIdx: 2,
      eyebrow: "03",
      title: t.servicesPage?.s3t || "Alquiler largo plazo",
      sub: t.servicesPage?.s3s || "Alquileres mensuales o anuales a residentes y segunda vivienda, con contratos bilingües.",
      img: "https://images.pexels.com/photos/1643389/pexels-photo-1643389.jpeg?auto=compress&cs=tinysrgb&w=1600",
      items: [
        t.servicesPage?.s3i1 || "Screening de inquilinos (referencias + solvencia)",
        t.servicesPage?.s3i2 || "Contratos bilingües adaptados a ley dominicana",
        t.servicesPage?.s3i3 || "Gestión de fianzas y depósitos",
        t.servicesPage?.s3i4 || "Inventario fotográfico entrada/salida",
        t.servicesPage?.s3i5 || "Cobro de rentas y conciliación mensual",
        t.servicesPage?.s3i6 || "Renovaciones y ajustes de precio anuales",
      ],
    },
    {
      k: "manage",
      interestIdx: 3,
      eyebrow: "04",
      title: t.servicesPage?.s4t || "Gestión integral (Property Management)",
      sub: t.servicesPage?.s4s || "Comisión mensual fija. El propietario se despreocupa: nosotros operamos la propiedad como si fuera nuestra.",
      img: "https://images.pexels.com/photos/261327/pexels-photo-261327.jpeg?auto=compress&cs=tinysrgb&w=1600",
      featured: true,
      items: [
        t.servicesPage?.s4i1 || "Mantenimiento preventivo y correctivo",
        t.servicesPage?.s4i2 || "Personal de limpieza, jardinería, piscina",
        t.servicesPage?.s4i3 || "Pago de servicios, impuestos, seguros",
        t.servicesPage?.s4i4 || "Inspecciones trimestrales documentadas",
        t.servicesPage?.s4i5 || "Gestión de inquilinos y emergencias 24/7",
        t.servicesPage?.s4i6 || "Reporte mensual financiero y operativo",
      ],
    },
  ];

  return (
    <section className="page page--services">
      <div className="page__head">
        <div className="container">
          <span className="eyebrow reveal-text">{t.nav.services}</span>
          <h1 className="page__title reveal-text">
            {t.servicesPage?.title || "Cuatro servicios, un estándar."}
          </h1>
          <p className="page__sub reveal-text">
            {t.servicesPage?.sub || "Todo lo que un propietario internacional necesita para comprar, vender, alquilar o simplemente despreocuparse de su propiedad en el norte dominicano."}
          </p>
        </div>
      </div>

      <div className="services-list">
        {services.map((s, i) => (
          <ServiceRow key={s.k} s={s} reverse={i % 2 === 1} t={t} />
        ))}
      </div>

      <div className="services__cta reveal">
        <div className="container">
          <h2 className="services__cta-title">
            {t.servicesPage?.ctaTitle || <>¿No está seguro <em>qué necesita</em>?</>}
          </h2>
          <p>{t.servicesPage?.ctaSub || "Una conversación inicial de 30 minutos, confidencial y sin compromiso, suele aclarar el camino."}</p>
          <a href="https://wa.me/18294832697" target="_blank" rel="noopener" className="btn-gold">
            <Icon.WhatsApp /> {t.servicesPage?.ctaBtn || "Agendar conversación"}
          </a>
        </div>
      </div>
    </section>
  );
}

function ServiceRow({ s, reverse, t }) {
  return (
    <article className={`service-row${reverse ? " service-row--reverse" : ""}${s.featured ? " service-row--featured" : ""}`}>
      <div className="service-row__img reveal">
        <img src={s.img} alt={s.title} loading="lazy" />
        <span className="service-row__num">{s.eyebrow}</span>
      </div>
      <div className="service-row__content reveal">
        {s.featured && <span className="service-row__tag">{t.servicesPage?.flagship || "Servicio insignia"}</span>}
        <h2 className="service-row__title">{s.title}</h2>
        <p className="service-row__sub">{s.sub}</p>
        <ul className="service-row__items">
          {s.items.map((it, i) => (
            <li key={i}>
              <span className="service-row__check"><Icon.Check /></span>
              <span>{it}</span>
            </li>
          ))}
        </ul>
        <a href="#contact" className="btn-text" onClick={(e) => {
          e.preventDefault();
          try {
            sessionStorage.setItem("lgm_contact_prefill", JSON.stringify({
              interestIdx: typeof s.interestIdx === "number" ? s.interestIdx : undefined,
              msg: `${t.servicesPage?.prefillMsg || "Me interesa el servicio"}: ${s.title}.`,
            }));
          } catch (_) { /* ignore */ }
          const el = document.querySelector("#contact");
          if (el) {
            el.scrollIntoView({ behavior: "smooth" });
            // trigger prefill effect re-run si Contact ya montado
            window.dispatchEvent(new Event("lgm_contact_prefill"));
          }
        }}>
          {t.servicesPage?.inquire || "Consultar este servicio"} <Icon.Arrow />
        </a>
      </div>
    </article>
  );
}

// ============================================================
// SELL PAGE — Formulario para solicitar valuación (/vender)
// ============================================================
const SELL_SUPABASE_URL = "https://vhlghqgkqvghlsfdiukv.supabase.co";
const SELL_SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZobGdocWdrcXZnaGxzZmRpdWt2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzYwOTYxMzUsImV4cCI6MjA5MTY3MjEzNX0.zxMer-1e0SQbUNtDADxeWEN2GaNJjR-9chxw90t6W2k";

function SellPage({ t, onNav }) {
  const { useState: uS, useEffect: uE, useRef: uR } = React;
  const [step, setStep] = uS(1);
  const [sending, setSending] = uS(false);
  const [uploading, setUploading] = uS(false);
  const [done, setDone] = uS(false);
  const [err, setErr] = uS(null);
  const [photos, setPhotos] = uS([]);
  const fileRef = uR(null);

  const [f, setF] = uS({
    owner_name: "", owner_phone: "", owner_email: "", owner_whatsapp: "",
    contact_preference: "whatsapp", best_time: "",
    property_type: "villa", listing_type: "sale",
    asking_price: "", rental_price: "", currency: "USD",
    location: "", region: "", address: "",
    beds: "", baths: "", parking: "",
    area_sqm: "", construction_sqm: "", lot_sqm: "", year_built: "",
    has_title: false, has_deslinde: false, in_private_community: false,
    description: "", features_text: "", owner_notes: "",
  });

  const set = (k, v) => setF(prev => ({ ...prev, [k]: v }));
  const toInt = s => { const n = parseInt(String(s).replace(/[^\d-]/g, ""), 10); return isNaN(n) ? null : n; };
  const toNum = s => { const n = parseFloat(String(s).replace(/[^\d.-]/g, "")); return isNaN(n) ? null : n; };

  uE(() => { window.scrollTo({ top: 0, behavior: "smooth" }); }, [step]);

  const validStep = () => {
    if (step === 1) {
      if (!f.owner_name.trim()) return "Escribe tu nombre";
      if (!f.owner_phone.trim()) return "Escribe tu teléfono";
    }
    if (step === 2) {
      if (!f.location.trim()) return "Indica la ubicación";
      if (f.listing_type !== "rent" && !f.asking_price) return "Indica el precio de venta";
      if (f.listing_type !== "sale" && !f.rental_price) return "Indica el precio de renta";
    }
    return null;
  };

  const next = () => {
    const e = validStep(); if (e) { setErr(e); return; }
    setErr(null); setStep(s => Math.min(4, s + 1));
  };
  const back = () => { setErr(null); setStep(s => Math.max(1, s - 1)); };

  async function uploadFile(file) {
    const safe = file.name.replace(/[^a-z0-9.\-_]/gi, "_");
    const path = `submissions/${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${safe}`;
    const url = `${SELL_SUPABASE_URL}/storage/v1/object/property-images/${path}`;
    const res = await fetch(url, {
      method: "POST",
      headers: {
        apikey: SELL_SUPABASE_KEY,
        Authorization: `Bearer ${SELL_SUPABASE_KEY}`,
        "Content-Type": file.type || "application/octet-stream",
        "x-upsert": "false",
      },
      body: file,
    });
    if (!res.ok) {
      const txt = await res.text();
      throw new Error(`Upload falló: ${res.status} ${txt}`);
    }
    return `${SELL_SUPABASE_URL}/storage/v1/object/public/property-images/${path}`;
  }

  async function handleFiles(list) {
    const files = Array.from(list || []).filter(x => x && x.type && x.type.startsWith("image/"));
    if (!files.length) return;
    setUploading(true); setErr(null);
    try {
      const urls = [];
      for (const file of files) { urls.push(await uploadFile(file)); }
      setPhotos(p => [...p, ...urls]);
    } catch (e) {
      setErr(e.message || "Error subiendo imágenes");
    } finally {
      setUploading(false);
    }
  }

  async function handleSubmit() {
    const e = validStep(); if (e) { setErr(e); return; }
    setErr(null); setSending(true);
    const features = f.features_text.split("\n").map(s => s.trim()).filter(Boolean);
    const payload = {
      owner_name: f.owner_name.trim(),
      owner_phone: f.owner_phone.trim(),
      owner_email: f.owner_email.trim() || null,
      owner_whatsapp: f.owner_whatsapp.trim() || null,
      contact_preference: f.contact_preference,
      best_time: f.best_time.trim() || null,
      property_type: f.property_type,
      listing_type: f.listing_type,
      asking_price: f.listing_type === "rent" ? null : toNum(f.asking_price),
      rental_price: f.listing_type === "sale" ? null : toNum(f.rental_price),
      currency: f.currency,
      location: f.location.trim(),
      region: f.region.trim() || null,
      address: f.address.trim() || null,
      beds: toInt(f.beds), baths: toInt(f.baths), parking: toInt(f.parking),
      area_sqm: toNum(f.area_sqm), construction_sqm: toNum(f.construction_sqm),
      lot_sqm: toNum(f.lot_sqm), year_built: toInt(f.year_built),
      has_title: !!f.has_title, has_deslinde: !!f.has_deslinde, in_private_community: !!f.in_private_community,
      description: f.description.trim() || null,
      features, photo_urls: photos,
      owner_notes: f.owner_notes.trim() || null,
      source: "landing_sell_banner",
      user_agent: (typeof navigator !== "undefined" ? navigator.userAgent : ""),
    };
    try {
      const res = await fetch(`${SELL_SUPABASE_URL}/rest/v1/property_submissions`, {
        method: "POST",
        headers: {
          apikey: SELL_SUPABASE_KEY,
          Authorization: `Bearer ${SELL_SUPABASE_KEY}`,
          "Content-Type": "application/json",
          Prefer: "return=minimal",
        },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const txt = await res.text();
        throw new Error(`Error ${res.status}: ${txt}`);
      }
      setDone(true);
    } catch (e) {
      setErr(e.message || "Error enviando solicitud");
    } finally {
      setSending(false);
    }
  }

  if (done) {
    return (
      <section className="sell reveal">
        <div className="sell__success">
          <div className="sell__success-icon">✓</div>
          <h1>Solicitud enviada</h1>
          <p>Gracias por confiar en <strong>Luis García Márquez</strong>. Revisaré tu propiedad y me pondré en contacto contigo en las próximas 24–48 horas por el medio que prefieras.</p>
          <button className="btn-gold" onClick={() => onNav("/")}>Volver al inicio</button>
        </div>
      </section>
    );
  }

  const stepLabels = ["Contacto", "Propiedad", "Detalles", "Fotos y extras"];

  return (
    <section className="sell reveal">
      <div className="sell__hero">
        <span className="eyebrow">Vender con LGM</span>
        <h1 className="sell__title">Solicita tu <em>valuación confidencial</em></h1>
        <p className="sell__sub">Completa los datos de tu propiedad. Luis García Márquez revisará cada caso y te contactará en 24–48h con un análisis de mercado personalizado.</p>
      </div>

      <div className="sell__progress">
        {stepLabels.map((label, i) => {
          const n = i + 1;
          const cls = n === step ? "active" : n < step ? "done" : "";
          return (
            <div key={n} className={`sell__step ${cls}`}>
              <span className="sell__step-num">0{n}</span>
              <span className="sell__step-label">{label}</span>
            </div>
          );
        })}
      </div>

      <div className="sell__form">
        {step === 1 && (
          <div className="sell__section">
            <h2>¿Cómo te contactamos?</h2>
            <p className="sell__hint">Datos privados. Solo Luis accede a esta información.</p>
            <div className="sell__grid">
              <div className="sell__field">
                <label>Nombre completo *</label>
                <input value={f.owner_name} onChange={e => set("owner_name", e.target.value)} placeholder="Ej. María Rodríguez" />
              </div>
              <div className="sell__field">
                <label>Teléfono *</label>
                <input value={f.owner_phone} onChange={e => set("owner_phone", e.target.value)} placeholder="+1 (829) 000-0000" />
              </div>
              <div className="sell__field">
                <label>WhatsApp</label>
                <input value={f.owner_whatsapp} onChange={e => set("owner_whatsapp", e.target.value)} placeholder="Mismo que teléfono si aplica" />
              </div>
              <div className="sell__field">
                <label>Email</label>
                <input type="email" value={f.owner_email} onChange={e => set("owner_email", e.target.value)} placeholder="tu@email.com" />
              </div>
              <div className="sell__field">
                <label>Contacto preferido</label>
                <Dropdown ariaLabel="Contacto preferido"
                  value={f.contact_preference}
                  onChange={e => set("contact_preference", e.target.value)}
                  options={[
                    { value: "whatsapp", label: "WhatsApp" },
                    { value: "phone", label: "Teléfono" },
                    { value: "email", label: "Email" },
                    { value: "any", label: "Cualquiera" },
                  ]} />
              </div>
              <div className="sell__field">
                <label>Mejor horario para llamar</label>
                <input value={f.best_time} onChange={e => set("best_time", e.target.value)} placeholder="Ej. Tardes 4–7pm" />
              </div>
            </div>
          </div>
        )}

        {step === 2 && (
          <div className="sell__section">
            <h2>Tu propiedad</h2>
            <p className="sell__hint">Ubicación y tipo. Luego pediremos detalles más específicos.</p>
            <div className="sell__grid">
              <div className="sell__field">
                <label>Tipo de propiedad</label>
                <Dropdown ariaLabel="Tipo de propiedad"
                  value={f.property_type}
                  onChange={e => set("property_type", e.target.value)}
                  options={[
                    { value: "villa", label: "Villa" },
                    { value: "apartment", label: "Apartamento" },
                    { value: "penthouse", label: "Penthouse" },
                    { value: "house", label: "Casa" },
                    { value: "land", label: "Terreno" },
                    { value: "commercial", label: "Local / Negocio comercial" },
                  ]} />
              </div>
              <div className="sell__field">
                <label>Operación</label>
                <Dropdown ariaLabel="Operación"
                  value={f.listing_type}
                  onChange={e => set("listing_type", e.target.value)}
                  options={[
                    { value: "sale", label: "Venta" },
                    { value: "rent", label: "Alquiler" },
                    { value: "vacation", label: "Alquiler vacacional" },
                  ]} />
              </div>
              <div className="sell__field sell__field--full">
                <label>Ubicación (zona / barrio) *</label>
                <input value={f.location} onChange={e => set("location", e.target.value)} placeholder="Ej. Costa Dorada, Playa Dorada" />
              </div>
              <div className="sell__field">
                <label>Región / Ciudad</label>
                <input value={f.region} onChange={e => set("region", e.target.value)} placeholder="Ej. Puerto Plata" />
              </div>
              <div className="sell__field">
                <label>Dirección exacta <span className="sell__hint-inline">(opcional, privada)</span></label>
                <input value={f.address} onChange={e => set("address", e.target.value)} placeholder="Calle, número…" />
              </div>
              {f.listing_type !== "rent" && (
                <div className="sell__field">
                  <label>Precio de venta aproximado *</label>
                  <div className="sell__currency-row">
                    <Dropdown ariaLabel="Moneda"
                      className="sell__currency-dd"
                      value={f.currency}
                      onChange={e => set("currency", e.target.value)}
                      options={[
                        { value: "USD", label: "USD" },
                        { value: "DOP", label: "DOP" },
                        { value: "EUR", label: "EUR" },
                      ]} />
                    <input value={f.asking_price} onChange={e => set("asking_price", e.target.value)} placeholder="850000" />
                  </div>
                </div>
              )}
              {f.listing_type !== "sale" && (
                <div className="sell__field">
                  <label>Precio de renta mensual *</label>
                  <div className="sell__currency-row">
                    <Dropdown ariaLabel="Moneda"
                      className="sell__currency-dd"
                      value={f.currency}
                      onChange={e => set("currency", e.target.value)}
                      options={[
                        { value: "USD", label: "USD" },
                        { value: "DOP", label: "DOP" },
                        { value: "EUR", label: "EUR" },
                      ]} />
                    <input value={f.rental_price} onChange={e => set("rental_price", e.target.value)} placeholder="3500" />
                  </div>
                </div>
              )}
            </div>
          </div>
        )}

        {step === 3 && (
          <div className="sell__section">
            <h2>Detalles</h2>
            <p className="sell__hint">Cuanta más información, mejor será la valuación.</p>
            <div className="sell__grid">
              <div className="sell__field"><label>Habitaciones</label><input value={f.beds} onChange={e => set("beds", e.target.value)} placeholder="3" /></div>
              <div className="sell__field"><label>Baños</label><input value={f.baths} onChange={e => set("baths", e.target.value)} placeholder="2" /></div>
              <div className="sell__field"><label>Parking (autos)</label><input value={f.parking} onChange={e => set("parking", e.target.value)} placeholder="2" /></div>
              <div className="sell__field"><label>Año de construcción</label><input value={f.year_built} onChange={e => set("year_built", e.target.value)} placeholder="2019" /></div>
              <div className="sell__field"><label>Área construcción (m²)</label><input value={f.construction_sqm} onChange={e => set("construction_sqm", e.target.value)} placeholder="320" /></div>
              <div className="sell__field"><label>Área total / solar (m²)</label><input value={f.area_sqm} onChange={e => set("area_sqm", e.target.value)} placeholder="450" /></div>
              <div className="sell__field"><label>Tamaño del lote (m²)</label><input value={f.lot_sqm} onChange={e => set("lot_sqm", e.target.value)} placeholder="600" /></div>
              <div className="sell__field sell__field--full">
                <div className="sell__checks">
                  <label className="sell__check"><input type="checkbox" checked={f.has_title} onChange={e => set("has_title", e.target.checked)} /><span>Tiene título de propiedad</span></label>
                  <label className="sell__check"><input type="checkbox" checked={f.has_deslinde} onChange={e => set("has_deslinde", e.target.checked)} /><span>Tiene deslinde</span></label>
                  <label className="sell__check"><input type="checkbox" checked={f.in_private_community} onChange={e => set("in_private_community", e.target.checked)} /><span>Está dentro de residencial / comunidad privada</span></label>
                </div>
              </div>
            </div>
          </div>
        )}

        {step === 4 && (
          <div className="sell__section">
            <h2>Fotos y descripción</h2>
            <p className="sell__hint">Sube al menos 4–6 fotos. Luis las revisará junto con los datos y preparará un borrador listo para publicar.</p>

            <div className="sell__field sell__field--full">
              <label>Fotos de la propiedad</label>
              <div className="sell__upload" onClick={() => fileRef.current?.click()}
                onDragOver={e => { e.preventDefault(); e.currentTarget.classList.add("drag"); }}
                onDragLeave={e => e.currentTarget.classList.remove("drag")}
                onDrop={e => { e.preventDefault(); e.currentTarget.classList.remove("drag"); handleFiles(e.dataTransfer.files); }}>
                <input ref={fileRef} type="file" multiple accept="image/*" className="sell__file-input" onChange={e => handleFiles(e.target.files)} />
                <div className="sell__upload-label">{uploading ? "Subiendo…" : "Arrastra aquí o haz clic para elegir imágenes"}</div>
                <div className="sell__upload-hint">JPG / PNG · hasta 20 fotos</div>
              </div>
              {photos.length > 0 && (
                <div className="sell__photos">
                  {photos.map((url, i) => (
                    <div key={i} className="sell__photo">
                      <img src={url} alt={`Foto ${i + 1}`} />
                      <button type="button" onClick={() => setPhotos(p => p.filter((_, j) => j !== i))} aria-label="Quitar">×</button>
                    </div>
                  ))}
                </div>
              )}
            </div>

            <div className="sell__grid" style={{ marginTop: 20 }}>
              <div className="sell__field sell__field--full">
                <label>Descripción de la propiedad</label>
                <textarea rows="4" value={f.description} onChange={e => set("description", e.target.value)} placeholder="Cuéntanos lo especial de tu propiedad: vistas, materiales, amenidades, historia…" />
              </div>
              <div className="sell__field sell__field--full">
                <label>Características <span className="sell__hint-inline">(una por línea)</span></label>
                <textarea rows="4" value={f.features_text} onChange={e => set("features_text", e.target.value)} placeholder={"Piscina\nVista al mar\nCocina italiana\nJardín tropical"} />
              </div>
              <div className="sell__field sell__field--full">
                <label>Notas adicionales para Luis</label>
                <textarea rows="3" value={f.owner_notes} onChange={e => set("owner_notes", e.target.value)} placeholder="Urgencia de venta, si está amueblada, motivo, etc." />
              </div>
            </div>
          </div>
        )}

        {err && <div className="sell__error">{err}</div>}

        <div className="sell__actions">
          {step > 1 && <button className="btn-line" onClick={back}>← Atrás</button>}
          <div className="sell__spacer" />
          {step < 4 && <button className="btn-gold" onClick={next}>Siguiente →</button>}
          {step === 4 && (
            <button className="btn-gold" onClick={handleSubmit} disabled={sending || uploading}>
              {sending ? "Enviando…" : "Enviar solicitud"}
            </button>
          )}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  useRoute, PageTransition, HomePage, PropertiesPage, AboutPage, ServicesPage, SellPage,
  FilterGroup, FilterPills, ListCard, ServiceRow,
});
