/* global React, ReactDOM */
const { useState, useEffect } = React;

const WONING_WORKER = 'https://inmobalia-proxy.tonicopy77.workers.dev';

// Inmobalia type codes — 1 & 2 = Appartement, 13 = Villa
const WONING_TYPE_MAP = {
  1:'Appartement', 2:'Appartement', 3:'Penthouse', 4:'Townhouse',
  5:'Studio', 6:'Bungalow', 7:'Grondstuk', 8:'Commercieel',
  9:'Garage', 10:'Boerderij', 11:'Duplex', 12:'Chalet', 13:'Villa',
  14:'Nieuwe ontwikkeling',
};

// City-code → stad naam (voor SEO-slugs, specifieker dan provincie)
// Codes zijn Inmobalia interne city IDs binnen een provincie
const WONING_CITY_MAP = {
  // Province 7 — Málaga / Costa del Sol (geverifieerd via beschrijvingen)
  4:'Benahavis', 5:'Marbella', 11:'Mijas', 12:'Fuengirola',
  21:'Mijas',    22:'Manilva', 24:'Marbella', 25:'Mijas', 26:'Mijas',
  // Province 3 — Alicante / Costa Blanca (toekomstig aanbod)
  // Province 30 — Murcia / Costa Cálida (toekomstig aanbod)
};

const WONING_PROV_MAP = {
  1:'Álava', 2:'Albacete', 3:'Alicante', 4:'Almería', 5:'Ávila',
  6:'Badajoz', 7:'Málaga', 8:'Barcelona', 9:'Burgos', 10:'Cáceres',
  11:'Cádiz', 12:'Castellón', 13:'Ciudad Real', 14:'Córdoba', 15:'A Coruña',
  16:'Cuenca', 17:'Girona', 18:'Granada', 19:'Guadalajara', 20:'Guipúzcoa',
  21:'Huelva', 22:'Huesca', 23:'Jaén', 24:'León', 25:'Lleida',
  26:'La Rioja', 27:'Lugo', 28:'Madrid', 29:'Málaga', 30:'Murcia',
  31:'Navarra', 32:'Ourense', 33:'Asturias', 34:'Palencia', 35:'Las Palmas',
  36:'Pontevedra', 37:'Salamanca', 38:'Tenerife', 39:'Cantabria', 40:'Segovia',
  41:'Sevilla', 42:'Soria', 43:'Tarragona', 44:'Teruel', 45:'Toledo',
  46:'Valencia', 47:'Valladolid', 48:'Vizcaya', 49:'Zamora', 50:'Zaragoza',
  51:'Ceuta', 52:'Melilla', 53:'Baleares', 54:'Ibiza', 55:'Menorca',
};

const FEATURE_NL = {
  'AmenitiesNear':'Voorzieningen nabij', 'TransportNear':'OV nabij',
  'Airconditioning':'Airconditioning', 'FullyFittedKitchen':'Volledig uitgeruste keuken',
  'UtilityRoom':'Bergruimte', 'Gym':'Gym', 'SecurityService24h':'Beveiliging 24u',
  'SeaView':'Zeezicht', 'Lift':'Lift', 'Unfurnished':'Ongestoffeerd',
  'Furnished':'Gemeubileerd', 'CloseToChildrenPlayground':'Speeltuin nabij',
  'CloseToSeaBeach':'Strand nabij', 'ExcellentCondition':'Uitstekende staat',
  'RecentlyRenovatedRefurbished':'Recent gerenoveerd', 'CloseToShops':'Winkels nabij',
  'CloseToTown':'Centrum nabij', 'CloseToPort':'Haven nabij', 'CloseToSchools':'Scholen nabij',
  'IndividualUnitsAC':'Individuele AC', 'MatureJardens':'Volwassen tuinen',
  'CloseToRestaurants':'Restaurants nabij', 'ConciergeService':'Conciërgerie',
  'GarageIncludedInPrice':'Garage inbegrepen', 'SwimmingPool':'Zwembad',
  'Garden':'Tuin', 'Terrace':'Terras', 'StorageRoom':'Berging',
  'Parking':'Parkeerplaats', 'MountainView':'Bergzicht', 'GolfView':'Golzicht',
  'Barbecue':'Barbecue', 'Jacuzzi':'Jacuzzi', 'SolarPanels':'Zonnepanelen',
  'Mountainside':'Bergflank', 'DoubleGlazing':'Dubbel glas',
  'GuestToilet':'Gastentoilet', 'VideoEntrance':'Video-intercom',
  'PrivateTerrace':'Privéterras', 'KitchenEquipped':'Keuken uitgerust',
  'InternetWifi':'Internet/Wi-Fi', 'FittedWardrobes':'Ingebouwde kasten',
  'GatedCommunity':'Beveiligd complex', 'BrandNew':'Nieuwbouw',
  'ParquetFloors':'Parketvloer', 'CoveredTerrace':'Overdekt terras',
};

// ─── SEO slug helpers ─────────────────────────────────────────────────────────
function toSlug(str) {
  return (str || '')
    .normalize('NFD').replace(/[̀-ͯ]/g, '')
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

function propertySlug(p, typeLabel, prov) {
  const name = p.name || p.urbanisation || p.urbanizacion || '';
  // Gebruik city-naam als die bekend is, anders provincie (voor betere SEO)
  const city = WONING_CITY_MAP[p.city] || null;
  const loc  = p.town || city || prov || '';
  const base = name ? toSlug(name) : toSlug((typeLabel || '') + ' ' + loc);
  const ref  = (p.reference || '').toLowerCase();
  return base + '-' + ref;
}

// ─── Beschrijving ophalen uit Inmobalia-detail ────────────────────────────────
// Geeft { text, isDutch } terug.
// Strategie: probeer expliciete NL-velden → expliciete EN-velden → brede scan.
function extractRawDescription(detail) {
  if (!detail) return { text: null, isDutch: false };

  // 1. Expliciete NL-kandidaten (meest specifiek → minst specifiek)
  const nlCandidates = [
    detail.descriptionNl,
    detail.description_nl,
    detail.dutchDescription,
    detail.dutch,
    detail.translations?.nl?.description,
    detail.translations?.nl,
    detail.nl?.description,
    detail.nl,
    detail.text_nl,
    detail.textNl,
    detail.commentsNl,
    detail.comments_nl,
    detail.bodyNl,
    detail.body_nl,
    // soms als genest language-object
    typeof detail.language === 'object' ? detail.language?.nl : null,
    // descriptions als object met taalcodes
    detail.descriptions?.nl?.description,
    detail.descriptions?.nl,
  ];
  for (const c of nlCandidates) {
    if (typeof c === 'string' && c.trim().length > 30) return { text: c.trim(), isDutch: true };
  }

  // 2. Expliciete EN/generieke kandidaten
  const enCandidates = [
    detail.descriptionEn,
    detail.description_en,
    detail.englishDescription,
    detail.en?.description,
    detail.translations?.en?.description,
    detail.descriptions?.en?.description,
    detail.descriptions?.en,
    detail.description,
    detail.shortDescription,
    detail.fullDescription,
    detail.longDescription,
    detail.comments,
    detail.commentsEn,
    detail.comments_en,
    detail.text,
    detail.textEn,
    detail.body,
    detail.bodyEn,
    detail.body_en,
  ];
  for (const c of enCandidates) {
    if (typeof c === 'string' && c.trim().length > 30) return { text: c.trim(), isDutch: false };
  }

  // 3. Brede scan: doorzoek ALLE top-level string-velden
  // Sla bekende korte metadata-velden over
  const SKIP = new Set([
    'reference','id','name','town','province','type','status','currency',
    'pool','garden','garage','parking','terrace','lift','image','photo',
    'thumb','url','slug','urbanisation','urbanizacion','area','zone',
    'country','salePrice','priceOnRequest','mtsBuild','mtsTerrace',
    'bedrooms','bathrooms','floors','constructYear','renovationYear',
  ]);
  for (const [key, val] of Object.entries(detail)) {
    if (SKIP.has(key) || SKIP.has(key.toLowerCase())) continue;
    if (typeof val === 'string' && val.trim().length > 80) {
      // Detecteer NL aan de hand van stopwoorden
      const isNl = /\b(de|het|een|van|op|in|te|en|is|er|dat|voor|met|zijn|aan|bij|ook|om|als|uit|nog|wel|maar|door)\b/i.test(val);
      console.log('[woning] beschrijving gevonden via brede scan, veld:', key, '| NL:', isNl);
      return { text: val.trim(), isDutch: isNl };
    }
  }

  // 4. Controleer ook geneste objecten één niveau diep (descriptions, translations, etc.)
  for (const [key, val] of Object.entries(detail)) {
    if (val && typeof val === 'object' && !Array.isArray(val)) {
      for (const [subKey, subVal] of Object.entries(val)) {
        if (typeof subVal === 'string' && subVal.trim().length > 80) {
          const isNl = /\b(de|het|een|van|op|in|te|en|is|er|dat|voor|met|zijn|aan|bij)\b/i.test(subVal);
          console.log('[woning] beschrijving in nested object:', key + '.' + subKey, '| NL:', isNl);
          return { text: subVal.trim(), isDutch: isNl };
        }
      }
    }
  }

  console.log('[woning] geen beschrijving gevonden. Detail keys:', Object.keys(detail));
  return { text: null, isDutch: false };
}

// ─── Beschrijving inkorten ────────────────────────────────────────────────────
function truncateDescription(text, maxWords = 350, maxParas = 4) {
  if (!text) return null;
  const paras = text.split(/\n{2,}/).map(p => p.replace(/\n/g, ' ').trim()).filter(Boolean);
  const sliced = paras.slice(0, maxParas).join('\n\n');
  const words  = sliced.split(/\s+/);
  if (words.length <= maxWords) return sliced;
  const cut    = words.slice(0, maxWords).join(' ');
  const lastDot = Math.max(cut.lastIndexOf('. '), cut.lastIndexOf('! '), cut.lastIndexOf('? '));
  if (lastDot > cut.length * 0.55) return cut.slice(0, lastDot + 1);
  return cut + '…';
}

// ─── Auto-vertaling via unofficiële Google Translate endpoint ─────────────────
function splitIntoChunks(text, maxLen) {
  const chunks = [];
  let rest = text;
  while (rest.length > maxLen) {
    const slice    = rest.slice(0, maxLen);
    const lastStop = Math.max(slice.lastIndexOf('. '), slice.lastIndexOf('! '), slice.lastIndexOf('? '));
    const cut      = lastStop > maxLen * 0.5 ? lastStop + 2 : maxLen;
    chunks.push(rest.slice(0, cut).trim());
    rest = rest.slice(cut).trim();
  }
  if (rest) chunks.push(rest);
  return chunks;
}

async function translateToNl(text) {
  if (!text || text.trim().length < 20) return text;
  const cacheKey = 'wv_nl_' + text.slice(0, 80).replace(/\W/g, '');
  try {
    const cached = sessionStorage.getItem(cacheKey);
    if (cached) return cached;
  } catch (_) {}
  const chunks = splitIntoChunks(text, 900);
  try {
    const parts = await Promise.all(chunks.map(async chunk => {
      const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=nl&dt=t&q=${encodeURIComponent(chunk)}`;
      const res  = await fetch(url, { cache: 'no-store' });
      const data = await res.json();
      if (Array.isArray(data) && Array.isArray(data[0])) {
        return data[0].map(s => (Array.isArray(s) ? s[0] : '')).filter(Boolean).join('');
      }
      return chunk;
    }));
    const result = parts.join(' ');
    try { sessionStorage.setItem(cacheKey, result); } catch (_) {}
    return result;
  } catch (_) {
    return null;
  }
}

// ─────────────────────────────────────────────────────────────────────────────

function useIsMobile(bp = 900) {
  const [m, setM] = useState(window.innerWidth < bp);
  useEffect(() => {
    const h = () => setM(window.innerWidth < bp);
    window.addEventListener('resize', h, { passive: true });
    return () => window.removeEventListener('resize', h);
  }, [bp]);
  return m;
}

function WoningPage({ wRef }) {
  const [prop,    setProp]    = useState(null);
  const [detail,  setDetail]  = useState(null);
  const [images,  setImages]  = useState([]);
  const [loading, setLoading] = useState(true);
  const [activeImg, setActiveImg] = useState(0);
  const [gate, setGate] = useState(null);
  const isMobile = useIsMobile();

  // Verwerkte beschrijving (altijd NL, ingekort)
  const [displayDesc,  setDisplayDesc]  = useState(null);
  const [translating,  setTranslating]  = useState(false);

  // Reveal-animaties voor BigCTA en andere reveal-fade elementen op deze pagina
  useReveal();

  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const listRes  = await fetch(`${WONING_WORKER}/?size=100`, { cache: 'no-store' });
        const listData = await listRes.json();
        const found    = (listData.content || []).find(x => x.reference === wRef);
        if (!found || cancelled) { setLoading(false); return; }
        setProp(found);

        const [detailRes, imgsRes, descRes] = await Promise.all([
          fetch(`${WONING_WORKER}/?id=${found.id}`),
          fetch(`${WONING_WORKER}/?id=${found.id}&images=true`),
          fetch(`${WONING_WORKER}/?id=${found.id}&descriptions=true`),
        ]);
        const det   = await detailRes.json();
        const imgs  = await imgsRes.json();
        const descs = await descRes.json().catch(() => []);
        if (cancelled) return;
        // Inject descriptions into detail object zodat extractRawDescription ze vindt
        if (Array.isArray(descs) && descs.length > 0) {
          const nlDesc = descs.find(d => (d.language || d.lang || '').toLowerCase() === 'nl');
          const enDesc = descs.find(d => (d.language || d.lang || '').toLowerCase() === 'en');
          if (nlDesc) det.descriptionNl = nlDesc.text || nlDesc.description || nlDesc.body || '';
          if (enDesc) det.descriptionEn = enDesc.text || enDesc.description || enDesc.body || '';
          console.log('[woning] descriptions geladen:', descs.map(d => d.language || d.lang));
        }
        setDetail(det);
        if (Array.isArray(imgs)) {
          const sorted = [...imgs].sort((a, b) =>
            (b.main ? 1 : 0) - (a.main ? 1 : 0) || (a.position || 0) - (b.position || 0)
          );
          setImages(sorted);
        }
      } catch (_) {}
      finally { if (!cancelled) setLoading(false); }
    }
    load();
    return () => { cancelled = true; };
  }, [wRef]);

  // Beschrijving verwerken zodra detail binnenkomt
  useEffect(() => {
    if (!detail) return;
    let cancelled = false;

    const { text, isDutch } = extractRawDescription(detail);

    if (!text) return; // geen beschrijving beschikbaar

    if (isDutch) {
      setDisplayDesc(truncateDescription(text));
      return;
    }

    // Niet-NL: inkort eerst, dan vertaal
    const truncated = truncateDescription(text);
    setTranslating(true);

    translateToNl(truncated).then(nl => {
      if (cancelled) return;
      setDisplayDesc(nl || truncated);
      setTranslating(false);
    });

    return () => { cancelled = true; };
  }, [detail]);

  // URL → SEO slug + document.title + meta description
  useEffect(() => {
    if (!prop) return;
    const tl   = WONING_TYPE_MAP[prop.type] || 'Woning';
    const pr   = WONING_PROV_MAP[prop.province] || 'Spanje';
    const slug = propertySlug(prop, tl, pr);

    const expected = '/woning/' + slug;
    if (window.location.pathname !== expected) {
      history.replaceState(null, '', expected);
      const canonical = document.getElementById('canonical-tag');
      if (canonical) canonical.href = 'https://www.viavastgoed.com' + expected;
    }

    const pageTitle = prop.name
      ? prop.name + ' — te koop in Spanje | VIA Vastgoed'
      : tl + ' te koop in ' + pr + ' | VIA Vastgoed';
    document.title = pageTitle;
  }, [prop]);

  // Meta description updaten zodra NL tekst beschikbaar is
  useEffect(() => {
    if (!displayDesc) return;
    const metaEl = document.querySelector('meta[name="description"]');
    if (metaEl) {
      const clean = displayDesc.replace(/\n+/g, ' ').trim();
      metaEl.setAttribute('content',
        clean.slice(0, 157) + (clean.length > 157 ? '…' : '')
      );
    }
  }, [displayDesc]);

  if (loading) {
    return (
      <div style={{ minHeight:'70vh', display:'flex', alignItems:'center', justifyContent:'center', flexDirection:'column', gap:'16px' }}>
        <div style={{ width:'28px', height:'28px', border:'2px solid var(--line)', borderTopColor:'var(--ink)', borderRadius:'50%', animation:'spin 0.8s linear infinite' }} />
        <span style={{ fontFamily:'var(--font-mono)', fontSize:'11px', letterSpacing:'0.12em', textTransform:'uppercase', color:'var(--muted)' }}>Woning laden…</span>
        <style>{'@keyframes spin { to { transform: rotate(360deg); } }'}</style>
      </div>
    );
  }

  if (!prop) {
    return (
      <div style={{ minHeight:'60vh', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:'24px', padding:'40px' }}>
        <p style={{ fontFamily:'var(--font-mono)', fontSize:'12px', letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--muted)' }}>Woning niet gevonden</p>
        <a href="/projecten" style={{ fontFamily:'var(--font-mono)', fontSize:'12px', color:'var(--accent)', textDecoration:'none' }}>← Terug naar projecten</a>
        <Footer />
      </div>
    );
  }

  const typeLabel = WONING_TYPE_MAP[prop.type]     || 'Woning';
  const prov      = WONING_PROV_MAP[prop.province] || 'Spanje';
  const price     = '€ ' + Number(prop.salePrice || 0).toLocaleString('nl-NL');

  const featureItems = (detail?.features || []).map(f => FEATURE_NL[f] || f);
  const extraItems   = [
    detail?.pool    && detail.pool   !== 'NONE' && (detail.pool   === 'COMMUNAL' ? 'Gemeenschappelijk zwembad' : 'Privézwembad'),
    detail?.garden  && detail.garden !== 'NONE' && (detail.garden === 'COMMUNAL' ? 'Gemeenschappelijke tuin'   : 'Privétuin'),
    detail?.garage  && detail.garage !== 'NONE' && (detail.garage === 'PRIVATE'  ? 'Privégarage'               : 'Garage'),
    detail?.constructYear  && ('Bouwjaar '    + detail.constructYear),
    detail?.renovationYear && ('Gerenoveerd ' + detail.renovationYear),
    detail?.floors         && (detail.floors  + ' verdiepingen'),
  ].filter(Boolean);
  const allFeatures = [...featureItems, ...extraItems];

  const costs = [
    detail?.community && { label:'VvE kosten',                    val:'€ ' + Number(detail.community).toLocaleString('nl-NL') + ' /jaar' },
    detail?.ibi       && { label:'Onroerend goed belasting (IBI)', val:'€ ' + Number(detail.ibi).toLocaleString('nl-NL')       + ' /jaar' },
    detail?.garbage   && { label:'Afvalstoffenheffing',            val:'€ ' + Number(detail.garbage).toLocaleString('nl-NL')   + ' /jaar' },
  ].filter(Boolean);

  const currentImg  = images[activeImg]?.url;
  const h1Content   = prop.name
    ? prop.name
    : <>{typeLabel} in <em style={{ fontStyle:'italic', color:'var(--accent)' }}>{prov}</em></>;

  // Nederlandse fallback als beschrijving helemaal ontbreekt
  const fallbackDesc = `Deze ${typeLabel.toLowerCase()} in ${prov} is te koop via VIA Vastgoed. Neem contact met ons op voor documentatie, een bezichtiging of persoonlijk advies.`;

  return (<>
    {/* Fotogalerij */}
    <div style={{ marginTop:'80px', background:'var(--bg-2)' }}>
      <div style={{ width:'100%', height: isMobile ? '260px' : '520px', overflow:'hidden', position:'relative' }}>
        {currentImg
          ? <img src={currentImg} alt={typeLabel + ' in ' + prov}
                 style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }} />
          : <div style={{ width:'100%', height:'100%', background:'linear-gradient(135deg, var(--bg-2) 0%, var(--line) 100%)' }} />
        }
      </div>
      {images.length > 1 && (
        <div style={{ display:'flex', gap:'3px', padding:'3px 0', overflowX:'auto', background:'var(--bg-2)', WebkitOverflowScrolling:'touch' }}>
          {images.slice(0, 8).map((img, i) => (
            <div key={i} onClick={() => setActiveImg(i)} style={{
              flex:'0 0 88px', height:'58px', overflow:'hidden', cursor:'pointer',
              opacity: activeImg === i ? 1 : 0.4,
              outline: activeImg === i ? '2px solid var(--ink)' : 'none',
              transition:'opacity 0.2s',
            }}>
              <img src={img.url} alt="" loading="lazy" style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }} />
            </div>
          ))}
        </div>
      )}
    </div>

    {/* Inhoud */}
    <section className="section" style={{ paddingTop:'clamp(40px,5vw,72px)', paddingBottom:'80px' }}>
      <div style={{
        maxWidth:'1200px', margin:'0 auto',
        display:              isMobile ? 'block'   : 'grid',
        gridTemplateColumns:  isMobile ? undefined : '1fr 360px',
        gap:'72px', alignItems:'start',
      }}>
        {/* Links */}
        <div>
          <a href="/projecten" style={{
            display:'inline-flex', alignItems:'center', gap:'6px',
            fontFamily:'var(--font-mono)', fontSize:'11px', letterSpacing:'0.1em', textTransform:'uppercase',
            color:'var(--muted)', textDecoration:'none', marginBottom:'36px',
          }}>
            <svg width="12" height="12" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M12 7H2M6 3l-4 4 4 4"/></svg>
            Projecten
          </a>

          <h1 style={{ fontFamily:'var(--font-display)', fontSize:'clamp(28px,4.5vw,54px)', fontWeight:'400', lineHeight:'1.08', letterSpacing:'-0.02em', marginBottom: isMobile ? '36px' : '48px' }}>
            {h1Content}
          </h1>

          {/* Specs */}
          <div style={{
            display:'grid',
            gridTemplateColumns: isMobile ? 'repeat(2,1fr)' : 'repeat(4,1fr)',
            gap:'1px', background:'var(--line)', border:'1px solid var(--line)', marginBottom:'48px',
          }}>
            {[
              { val: prop.mtsBuild   || '—', lab: 'm² Wonen'    },
              { val: prop.bedrooms   || '—', lab: 'Slaapkamers' },
              { val: prop.bathrooms  || '—', lab: 'Badkamers'   },
              { val: prop.mtsTerrace || '—', lab: 'm² Terras'   },
            ].map(s => (
              <div key={s.lab} style={{ background:'var(--bg)', padding:'24px 12px', textAlign:'center' }}>
                <div style={{ fontFamily:'var(--font-display)', fontSize:'clamp(26px,3vw,40px)', fontWeight:'400', letterSpacing:'-0.02em', marginBottom:'8px' }}>{s.val}</div>
                <div style={{ fontFamily:'var(--font-mono)', fontSize:'9px', letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--muted)' }}>{s.lab}</div>
              </div>
            ))}
          </div>

          {/* Omschrijving — altijd NL */}
          <div style={{ marginBottom:'48px' }}>
            <div className="eyebrow" style={{ marginBottom:'20px' }}><span className="dot"></span>Over deze woning</div>

            {translating ? (
              <div style={{ display:'flex', alignItems:'center', gap:'10px', color:'var(--muted)', fontFamily:'var(--font-mono)', fontSize:'11px', letterSpacing:'0.08em' }}>
                <div style={{ width:'14px', height:'14px', border:'2px solid var(--line)', borderTopColor:'var(--muted)', borderRadius:'50%', animation:'spin 0.8s linear infinite', flexShrink:0 }} />
                Beschrijving vertalen…
              </div>
            ) : (() => {
              const text = displayDesc || fallbackDesc;
              const paras = text.split(/\n{2,}/).filter(s => s.trim());
              return paras.map((para, i) => (
                <p key={i} style={{ lineHeight:'1.75', color:'var(--ink)', maxWidth:'580px', fontSize:'15px', marginBottom: i < paras.length - 1 ? '14px' : 0 }}>
                  {para.trim()}
                </p>
              ));
            })()}
          </div>

          {/* Kenmerken */}
          {allFeatures.length > 0 && (
            <div style={{ marginBottom:'48px' }}>
              <div className="eyebrow" style={{ marginBottom:'20px' }}><span className="dot"></span>Kenmerken</div>
              <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(min(200px,100%), 1fr))', gap:'8px' }}>
                {allFeatures.map((f, i) => (
                  <div key={i} style={{
                    padding:'10px 14px', border:'1px solid var(--line)',
                    fontFamily:'var(--font-mono)', fontSize:'12px', letterSpacing:'0.04em', color:'var(--ink)',
                  }}>{f}</div>
                ))}
              </div>
            </div>
          )}

          {/* Kosten */}
          {costs.length > 0 && (
            <div>
              <div className="eyebrow" style={{ marginBottom:'20px' }}><span className="dot"></span>Jaarlijkse kosten</div>
              <div style={{ border:'1px solid var(--line)' }}>
                {costs.map((c, i) => (
                  <div key={i} style={{
                    display:'flex', justifyContent:'space-between', alignItems:'center',
                    padding:'14px 20px',
                    borderBottom: i < costs.length - 1 ? '1px solid var(--line)' : 'none',
                    fontFamily:'var(--font-mono)', fontSize:'12px', letterSpacing:'0.04em',
                  }}>
                    <span style={{ color:'var(--muted)' }}>{c.label}</span>
                    <span style={{ color:'var(--ink)' }}>{c.val}</span>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>

        {/* Rechts — sticky prijskaart */}
        <div style={{ position:isMobile ? 'static' : 'sticky', top:'100px', marginTop:isMobile ? '48px' : '0' }}>
          <div style={{ border:'1px solid var(--line)', padding:'36px' }}>
            <div style={{ fontFamily:'var(--font-mono)', fontSize:'10px', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--muted)', marginBottom:'8px' }}>
              Vraagprijs
            </div>
            <div style={{ fontFamily:'var(--font-display)', fontSize:'clamp(30px,4vw,44px)', fontWeight:'600', letterSpacing:'-0.02em', marginBottom:'32px', color:'var(--ink)' }}>
              {price}
            </div>

            <button
              onClick={() => setGate({ mode:'contact', project:{ naam: prop.name || typeLabel + ' in ' + prov, ref: prop.reference } })}
              className="cta-pill"
              style={{ width:'100%', padding:'18px 24px', fontSize:'14px', border:0, cursor:'pointer', font:'inherit', display:'flex', justifyContent:'center' }}
              data-cursor-hover
            >
              <span>Meer informatie aanvragen</span>
              <svg className="arrow" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5" width="14" height="14"><path d="M2 7h10M8 3l4 4-4 4"/></svg>
            </button>

            <p style={{ marginTop:'14px', fontFamily:'var(--font-mono)', fontSize:'11px', letterSpacing:'0.04em', color:'var(--muted)', textAlign:'center', lineHeight:'1.65' }}>
              Je wordt zo snel mogelijk persoonlijk<br/>benaderd door een van onze adviseurs.
            </p>
          </div>
        </div>
      </div>
    </section>

    <BigCTA />
    <Footer />
    <LeadGate open={!!gate} mode={gate?.mode} project={gate?.project} onClose={() => setGate(null)} />
  </>);
}
