// Shared components for the Gulf Oasis prototype.

const { useState, useEffect, useRef, useMemo } = React;

// ─── Icon: minimal stroke set ───────────────────────────────────────────────
function Icon({ name, className = 'w-4 h-4', stroke = 1.5 }) {
  const common = { width: '1em', height: '1em', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round', className };
  switch (name) {
    case 'arrow':   return <svg {...common}><path d="M5 12h14M13 6l6 6-6 6"/></svg>;
    case 'arrow-up-right': return <svg {...common}><path d="M7 17 17 7M9 7h8v8"/></svg>;
    case 'check':   return <svg {...common}><path d="M5 12.5 10 17l9-10"/></svg>;
    case 'minus':   return <svg {...common}><path d="M5 12h14"/></svg>;
    case 'plus':    return <svg {...common}><path d="M12 5v14M5 12h14"/></svg>;
    case 'cal':     return <svg {...common}><rect x="3.5" y="5" width="17" height="15" rx="1.5"/><path d="M3.5 10h17M8 3v4M16 3v4"/></svg>;
    case 'user':    return <svg {...common}><circle cx="12" cy="8" r="3.5"/><path d="M5 20c1.2-3.5 4-5.5 7-5.5s5.8 2 7 5.5"/></svg>;
    case 'kitchen': return <svg {...common}><rect x="4" y="3" width="16" height="18" rx="1"/><path d="M4 11h16M9 7h.01M9 17h6M9 15h6"/></svg>;
    case 'laundry': return <svg {...common}><rect x="4" y="3" width="16" height="18" rx="1.5"/><circle cx="12" cy="13" r="4.5"/><path d="M7.5 6.5h.01M10.5 6.5h.01"/></svg>;
    case 'bed':     return <svg {...common}><path d="M3 18V8M21 18v-5a3 3 0 0 0-3-3H3M3 14h18M3 21v-3M21 21v-3"/></svg>;
    case 'sqm':     return <svg {...common}><path d="M4 4h16v16H4z"/><path d="M4 9h2M4 14h2M4 19h2M9 20v-2M14 20v-2M19 20v-2"/></svg>;
    case 'people':  return <svg {...common}><circle cx="9" cy="9" r="3"/><circle cx="17" cy="10" r="2.5"/><path d="M3 20c1-3 3.4-4.5 6-4.5s5 1.5 6 4.5M14.5 20c.6-2 2.3-3 4.5-3 1.4 0 2.6.4 3.5 1"/></svg>;
    case 'wifi':    return <svg {...common}><path d="M2 9.5c5.5-5 14.5-5 20 0M5.5 13c3.5-3 9.5-3 13 0M9 16.5c1.7-1.4 4.3-1.4 6 0"/><circle cx="12" cy="20" r=".8" fill="currentColor"/></svg>;
    case 'parking': return <svg {...common}><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 17V7h4a3 3 0 0 1 0 6H9"/></svg>;
    case 'pool':    return <svg {...common}><path d="M3 18c2-1.5 4-1.5 6 0s4 1.5 6 0 4-1.5 6 0M3 14c2-1.5 4-1.5 6 0s4 1.5 6 0 4-1.5 6 0M8 12V6a2 2 0 0 1 4 0v6M16 12V6a2 2 0 0 1 4 0v6"/></svg>;
    case 'gym':     return <svg {...common}><path d="M3 9v6M21 9v6M6 6v12M18 6v12M6 12h12"/></svg>;
    case 'sauna':   return <svg {...common}><path d="M4 21h16M6 21V9a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v12M9 4c0 1 1 1 1 2s-1 1-1 2M13 4c0 1 1 1 1 2s-1 1-1 2"/></svg>;
    case 'jacuzzi': return <svg {...common}><path d="M3 12h18M3 12v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6M7 12V7a2 2 0 0 1 4 0M14 6c1 .5 1 1.5 0 2s-1 1.5 0 2M17 6c1 .5 1 1.5 0 2s-1 1.5 0 2"/></svg>;
    case 'desk':    return <svg {...common}><path d="M3 9h18M5 9v11M19 9v11M9 13h6"/></svg>;
    case 'metro':   return <svg {...common}><rect x="5" y="3" width="14" height="14" rx="3"/><path d="M5 12h14M9 17l-2 4M15 17l2 4"/><circle cx="9" cy="8" r=".8" fill="currentColor"/><circle cx="15" cy="8" r=".8" fill="currentColor"/></svg>;
    case 'pin':     return <svg {...common}><path d="M12 21s7-6.5 7-12a7 7 0 1 0-14 0c0 5.5 7 12 7 12Z"/><circle cx="12" cy="9" r="2.5"/></svg>;
    case 'whatsapp':return <svg {...common} stroke="none" fill="currentColor"><path d="M12 2a10 10 0 0 0-8.5 15.2L2 22l4.9-1.4A10 10 0 1 0 12 2Zm5.6 14.4c-.2.6-1.2 1.2-1.7 1.3-.5.1-1 .1-3.2-.7-2.7-1-4.4-3.7-4.5-3.9-.1-.2-1-1.4-1-2.6s.6-1.9.9-2.1c.2-.2.5-.3.7-.3h.5c.2 0 .4 0 .6.4l.8 2c.1.2 0 .4-.1.5l-.4.5c-.1.1-.3.3-.1.6.2.3.8 1.4 1.8 2.2 1.3 1.1 2.3 1.5 2.6 1.6.3.1.5.1.7-.1l1-1.1c.2-.2.4-.2.6-.1l1.9.9c.2.1.4.2.4.3 0 .1 0 .9-.5 1.5Z"/></svg>;
    case 'sun':     return <svg {...common}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>;
    case 'globe':   return <svg {...common}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 3 2.5 15 0 18M12 3c-2.5 3-2.5 15 0 18"/></svg>;
    case 'menu':    return <svg {...common}><path d="M4 7h16M4 12h16M4 17h16"/></svg>;
    case 'x':       return <svg {...common}><path d="M6 6l12 12M18 6 6 18"/></svg>;
    case 'shield':  return <svg {...common}><path d="M12 3 4 6v6c0 5 3.5 8.5 8 9 4.5-.5 8-4 8-9V6l-8-3Z"/><path d="m9 12 2.2 2.2L15 10.5"/></svg>;
    case 'leaf':    return <svg {...common}><path d="M4 20c0-8 6-14 16-15 0 9-6 16-16 15Z"/><path d="M4 20c4-4 8-7 14-11"/></svg>;
    default: return null;
  }
}

// ─── Atom: stat numeral ─────────────────────────────────────────────────────
function Stat({ value, unit, label, size = 'lg' }) {
  const sizes = {
    sm: 'text-[64px] md:text-[88px]',
    md: 'text-[96px] md:text-[140px]',
    lg: 'text-[140px] md:text-[200px]',
  };
  return (
    <div className="flex flex-col">
      <div className="flex items-baseline gap-2">
        <span className={`stat-num ${sizes[size]} text-teal`}>{value}</span>
        {unit && <span className="num text-2xl md:text-3xl text-teal-dark/80">{unit}</span>}
      </div>
      {label && <div className="mt-2 text-sm tracking-wide uppercase ink-soft">{label}</div>}
    </div>
  );
}

// ─── Atom: placeholder slot for missing photography ─────────────────────────
function Placeholder({ label, sub, className = '', tone = 'sand' }) {
  return (
    <div className={`relative overflow-hidden ${tone === 'dim' ? 'ph-stripes dim' : 'ph-stripes'} ${className}`}>
      <div className="absolute inset-0 flex flex-col items-start justify-end p-5 md:p-7">
        <div className="mono text-[10px] tracking-[0.18em] uppercase text-walnut/80 mb-1">
          {'// reshoot'}
        </div>
        <div className="mono text-[12px] md:text-[13px] text-walnut leading-tight max-w-[28ch]">
          {label}
        </div>
        {sub && <div className="mono text-[11px] mt-1 text-walnut/70 max-w-[34ch] leading-snug">{sub}</div>}
      </div>
      <div className="absolute top-3 right-3 mono text-[10px] text-walnut/60 tracking-[0.15em]">{'GO-PH'}</div>
    </div>
  );
}

// ─── Logo wordmark ──────────────────────────────────────────────────────────
function Logo({ className = '' }) {
  return (
    <a href="#home" className={`group inline-flex items-center gap-2.5 ${className}`} aria-label="Gulf Oasis Hotel Apartments — Home">
      <svg width="22" height="22" viewBox="0 0 24 24" className="text-teal">
        <circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" strokeWidth="1.2"/>
        <path d="M12 4 c3 3 3 13 0 16 M12 4 c-3 3 -3 13 0 16" fill="none" stroke="currentColor" strokeWidth="1.2"/>
        <circle cx="12" cy="12" r="2" fill="currentColor"/>
      </svg>
      <div className="leading-none">
        <div className="font-display text-[17px] text-ink">Gulf Oasis</div>
        <div className="mono text-[9px] tracking-[0.22em] uppercase ink-soft mt-0.5">Hotel Apartments · Tecom</div>
      </div>
    </a>
  );
}

// ─── Top Nav ────────────────────────────────────────────────────────────────
function Navbar({ route, setRoute, lang, setLang, langSwitcherEnabled, openBook }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  const label = (i) => lang === 'ar' ? i.labelAr : lang === 'ru' ? i.labelRu : i.label;
  const routable = ['home', 'apartments', 'long-stay'];
  return (
    <header className={`sticky top-0 z-40 transition-all ${scrolled ? 'bg-cream/90 backdrop-blur-md border-b hairline' : ''}`}>
      <div className="max-w-[1320px] mx-auto px-6 md:px-10 flex items-center justify-between h-[72px] md:h-[80px]">
        <Logo />
        <nav className="hidden lg:flex items-center gap-8 text-[14px] text-ink">
          {NAV_ITEMS.map((item) => (
            <a key={item.id}
               href={`#${item.id}`}
               onClick={(e) => { if (routable.includes(item.id)) { e.preventDefault(); setRoute(item.id); window.scrollTo({ top: 0, behavior: 'smooth' }); } }}
               data-active={route === item.id}
               className="nav-link">
              {label(item)}
            </a>
          ))}
        </nav>
        <div className="flex items-center gap-3">
          {langSwitcherEnabled && (
            <div className="hidden md:flex items-center gap-1 chip" role="tablist" aria-label="Language">
              <Icon name="globe" className="w-3.5 h-3.5"/>
              {['en','ar','ru'].map(l => (
                <button key={l}
                        onClick={() => setLang(l)}
                        aria-pressed={lang===l}
                        className={`px-1.5 py-0.5 rounded uppercase text-[10.5px] tracking-[0.14em] ${lang===l ? 'text-ink font-medium' : 'text-ink-soft hover:text-ink'}`}>
                  {l}
                </button>
              ))}
            </div>
          )}
          <button onClick={openBook}
                  className="hidden md:inline-flex items-center gap-2 px-4 py-2.5 rounded-full bg-teal text-cream text-[13.5px] tracking-tight hover:bg-teal-dark transition">
            Book direct <Icon name="arrow" className="w-3.5 h-3.5"/>
          </button>
          <button onClick={openBook} className="md:hidden chip solid">Book</button>
        </div>
      </div>
    </header>
  );
}

// ─── Booking widget (interactive: dates + guests + length-of-stay rate hint) ───
function BookingWidget({ variant = 'inline', onBookClick }) {
  const today = new Date();
  const fmt = (d) => d.toISOString().slice(0,10);
  const plus = (d, n) => { const x = new Date(d); x.setDate(x.getDate()+n); return x; };
  const [ci, setCi] = useState(fmt(plus(today, 14)));
  const [co, setCo] = useState(fmt(plus(today, 22)));
  const [adults, setAdults] = useState(2);
  const [children, setChildren] = useState(0);

  const nights = useMemo(() => {
    const a = new Date(ci), b = new Date(co);
    return Math.max(1, Math.round((b - a) / 86400000));
  }, [ci, co]);

  const tier = nights >= 28 ? 'monthly' : nights >= 7 ? 'weekly' : 'nightly';
  const tierLabel = { nightly: 'Nightly rate', weekly: 'Weekly rate · save ≈20%', monthly: 'Monthly rate · save ≈33%' }[tier];
  const fromUSD = tier === 'monthly' ? 34 : tier === 'weekly' ? 41 : 51;
  const fromAED = Math.round(fromUSD * 3.67);

  const stepperBtn = 'w-7 h-7 rounded-full border hairline flex items-center justify-center hover:bg-sand transition disabled:opacity-30 disabled:cursor-not-allowed';

  return (
    <div className={`bg-cream border hairline rounded-[3px] shadow-[0_24px_80px_-30px_rgba(16,54,66,0.35)] ${variant==='hero' ? 'p-6 md:p-7' : 'p-5'}`}>
      <div className="flex items-center justify-between mb-4">
        <div className="mono text-[10px] tracking-[0.22em] uppercase ink-soft">Direct booking · own PMS</div>
        <div className="chip !py-0.5 !px-2 !text-[10.5px]">
          <Icon name="shield" className="w-3 h-3 text-teal"/> Best-rate guarantee
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3">
        <label className="block">
          <div className="mono text-[10px] tracking-[0.18em] uppercase ink-soft mb-1.5 flex items-center gap-1.5"><Icon name="cal" className="w-3 h-3"/> Check-in</div>
          <input type="date" value={ci} onChange={(e) => setCi(e.target.value)}
                 className="w-full bg-transparent border-b hairline pb-1.5 text-[15px] focus:outline-none focus:border-teal"/>
        </label>
        <label className="block">
          <div className="mono text-[10px] tracking-[0.18em] uppercase ink-soft mb-1.5 flex items-center gap-1.5"><Icon name="cal" className="w-3 h-3"/> Check-out</div>
          <input type="date" value={co} min={fmt(plus(new Date(ci),1))} onChange={(e) => setCo(e.target.value)}
                 className="w-full bg-transparent border-b hairline pb-1.5 text-[15px] focus:outline-none focus:border-teal"/>
        </label>
      </div>

      <div className="grid grid-cols-2 gap-3 mt-4">
        <div>
          <div className="mono text-[10px] tracking-[0.18em] uppercase ink-soft mb-1.5 flex items-center gap-1.5"><Icon name="user" className="w-3 h-3"/> Adults</div>
          <div className="flex items-center justify-between border-b hairline pb-1.5">
            <button onClick={() => setAdults(Math.max(1, adults-1))} className={stepperBtn} disabled={adults<=1} aria-label="Fewer adults"><Icon name="minus" className="w-3 h-3"/></button>
            <span className="text-[15px] num text-ink">{adults}</span>
            <button onClick={() => setAdults(Math.min(4, adults+1))} className={stepperBtn} disabled={adults>=4} aria-label="More adults"><Icon name="plus" className="w-3 h-3"/></button>
          </div>
        </div>
        <div>
          <div className="mono text-[10px] tracking-[0.18em] uppercase ink-soft mb-1.5 flex items-center gap-1.5"><Icon name="user" className="w-3 h-3"/> Children</div>
          <div className="flex items-center justify-between border-b hairline pb-1.5">
            <button onClick={() => setChildren(Math.max(0, children-1))} className={stepperBtn} disabled={children<=0} aria-label="Fewer children"><Icon name="minus" className="w-3 h-3"/></button>
            <span className="text-[15px] num text-ink">{children}</span>
            <button onClick={() => setChildren(Math.min(4, children+1))} className={stepperBtn} disabled={children>=4} aria-label="More children"><Icon name="plus" className="w-3 h-3"/></button>
          </div>
        </div>
      </div>

      <div className="mt-5 p-4 rounded-[2px] bg-sand/55">
        <div className="flex items-baseline justify-between gap-3">
          <div>
            <div className="mono text-[10px] tracking-[0.22em] uppercase text-teal-dark">{tierLabel}</div>
            <div className="mt-1.5 flex items-baseline gap-1">
              <span className="num text-[44px] leading-none text-teal">{fromUSD}</span>
              <span className="text-sm text-ink-soft">USD · from</span>
            </div>
            <div className="mono text-[11px] ink-soft mt-1">≈ AED {fromAED} / night · {nights} {nights===1?'night':'nights'}</div>
          </div>
          <div className="text-right">
            <div className="mono text-[10px] tracking-[0.18em] uppercase ink-soft">Estimated</div>
            <div className="num text-2xl text-teal-dark mt-1">{(fromUSD*nights).toLocaleString()}<span className="text-base ink-soft not-italic font-sans"> USD</span></div>
          </div>
        </div>
      </div>

      <button onClick={onBookClick}
              className="mt-4 w-full inline-flex items-center justify-center gap-2 bg-teal text-cream py-3.5 rounded-[2px] hover:bg-teal-dark transition text-[14px] tracking-tight">
        See available apartments <Icon name="arrow" className="w-4 h-4"/>
      </button>

      <div className="mt-3 flex items-center justify-between mono text-[10.5px] ink-soft">
        <span>No commission · Free cancellation up to 48h</span>
        <span>EN · AED / USD</span>
      </div>
    </div>
  );
}

// ─── Apartment Card ─────────────────────────────────────────────────────────
function ApartmentCard({ apt, onPick, dense = false }) {
  const hasPhoto = apt.photoOk === true || apt.photoOk === 'partial';
  return (
    <article className="group flex flex-col bg-cream border hairline overflow-hidden">
      <div className="relative aspect-[4/3] overflow-hidden">
        {hasPhoto ? (
          <img src={apt.photo} alt={`${apt.name} apartment`} className="w-full h-full object-cover warm-photo transition-transform duration-700 group-hover:scale-[1.02]"/>
        ) : (
          <Placeholder label={`${apt.name} — full apartment frame`} sub={apt.photoNote} className="w-full h-full"/>
        )}
        {apt.photoOk === 'partial' && (
          <div className="absolute bottom-3 left-3 chip mono !text-[10px] bg-cream/90">
            <Icon name="leaf" className="w-3 h-3 text-walnut"/> Partial — reshoot pending
          </div>
        )}
        {!apt.visibleOnDirect && (
          <div className="absolute top-3 left-3 chip solid !text-[10px]">
            Now bookable direct
          </div>
        )}
        <div className="absolute top-3 right-3 px-2 py-1 bg-cream/95 text-[11px] mono tracking-[0.06em]">
          <span className="num text-teal text-[15px] mr-1">{apt.sqm}</span>m²
        </div>
      </div>

      <div className="p-5 md:p-6 flex flex-col gap-3 flex-1">
        <div className="flex items-start justify-between gap-3">
          <h3 className="font-display text-[22px] md:text-[26px]">{apt.name}</h3>
          <div className="text-right shrink-0">
            <div className="mono text-[9.5px] tracking-[0.18em] uppercase ink-soft">from / night</div>
            <div className="num text-[24px] text-teal leading-none mt-0.5">${apt.fromNight}</div>
          </div>
        </div>

        <div className="grid grid-cols-2 gap-x-3 gap-y-1.5 text-[12.5px] ink-soft">
          <div className="flex items-center gap-1.5"><Icon name="bed" className="w-3.5 h-3.5 text-walnut"/> {apt.bed}</div>
          <div className="flex items-center gap-1.5"><Icon name="people" className="w-3.5 h-3.5 text-walnut"/> Sleeps {apt.sleeps}</div>
          <div className="flex items-center gap-1.5"><Icon name="kitchen" className="w-3.5 h-3.5 text-walnut"/> {apt.kitchen}</div>
          <div className="flex items-center gap-1.5"><Icon name="laundry" className="w-3.5 h-3.5 text-walnut"/> {apt.laundry===true ? 'In-unit laundry' : apt.laundry || 'Hotel laundry'}</div>
        </div>

        {!dense && (
          <div className="text-[13px] text-ink leading-snug border-t hairline pt-3 mt-1">
            <span className="mono text-[10px] tracking-[0.18em] uppercase ink-soft mr-2">Best for</span>
            {apt.bestFor}
          </div>
        )}

        <div className="mt-auto pt-3 flex items-center justify-between">
          <div className="mono text-[11px] ink-soft">
            Weekly <span className="num text-teal text-[15px] ml-0.5">${apt.fromWeek}</span> · Monthly <span className="num text-teal text-[15px] ml-0.5">${apt.fromMonth}</span>
          </div>
          <button onClick={() => onPick && onPick(apt)} className="inline-flex items-center gap-1 text-[13px] text-teal hover:text-teal-dark">
            Book direct <Icon name="arrow" className="w-3.5 h-3.5"/>
          </button>
        </div>
      </div>
    </article>
  );
}

// ─── Comparison table (sticky-first-column scroll on mobile) ────────────────
function ComparisonTable({ apartments }) {
  const rows = [
    { k: 'sqm',      label: 'Size',         render: a => <><span className="num text-teal text-[18px]">{a.sqm}</span> m²</> },
    { k: 'sleeps',   label: 'Sleeps',       render: a => <>{a.sleeps}</> },
    { k: 'bed',      label: 'Bedding',      render: a => a.bed },
    { k: 'kitchen',  label: 'Kitchen',      render: a => a.kitchen },
    { k: 'laundry',  label: 'In-unit laundry', render: a => a.laundry===true ? <Icon name="check" className="w-4 h-4 text-teal" stroke={2}/> : a.laundry ? <span className="text-[12px] ink-soft">{a.laundry}</span> : <span className="ink-soft text-[12px]">—</span> },
    { k: 'balcony',  label: 'Balcony',      render: a => a.balcony===true ? <Icon name="check" className="w-4 h-4 text-teal" stroke={2}/> : <span className="ink-soft text-[12px]">{a.balcony || '—'}</span> },
    { k: 'best',     label: 'Best for',     render: a => <span className="text-[12.5px]">{a.bestFor}</span> },
    { k: 'rate',     label: 'From / night', render: a => <span className="num text-teal text-[20px]">${a.fromNight}</span> },
    { k: 'monthly',  label: 'From / month',  render: a => <span className="num text-teal text-[20px]">${a.fromMonth}<span className="text-[12px] ink-soft not-italic font-sans">/n</span></span> },
  ];
  return (
    <div className="border hairline bg-cream">
      <div className="overflow-x-auto no-scrollbar">
        <table className="min-w-[920px] w-full text-left text-[13px]">
          <thead>
            <tr className="border-b hairline">
              <th className="sticky left-0 bg-cream py-4 pl-5 pr-3 w-[160px] mono text-[10px] tracking-[0.18em] uppercase ink-soft font-normal align-bottom">All six types</th>
              {apartments.map(a => (
                <th key={a.id} className="py-4 px-4 align-bottom min-w-[150px]">
                  <div className="font-display text-[18px]">{a.name}</div>
                  {!a.visibleOnDirect && <div className="mt-1 mono text-[9.5px] tracking-[0.14em] uppercase text-teal">New on direct</div>}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {rows.map(r => (
              <tr key={r.k} className="border-b hairline last:border-b-0">
                <td className="sticky left-0 bg-cream py-3.5 pl-5 pr-3 mono text-[10.5px] tracking-[0.14em] uppercase ink-soft">{r.label}</td>
                {apartments.map(a => (
                  <td key={a.id} className="py-3.5 px-4 text-ink">{r.render(a)}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ─── Review badges (KAYAK, Booking.com, Tripadvisor) ────────────────────────
function ReviewBadges() {
  return (
    <div className="flex flex-wrap gap-3 md:gap-4">
      {RATING_BADGES.map((b, i) => (
        <div key={i} className="flex items-center gap-3 bg-cream border hairline px-4 py-3">
          <div className="num text-[28px] text-teal leading-none">{b.score}</div>
          <div className="leading-tight">
            <div className="text-[12.5px] text-ink">{b.source} · <span className="ink-soft">{b.label}</span></div>
            <div className="mono text-[10.5px] ink-soft tracking-[0.08em]">{b.count.toLocaleString()} verified reviews</div>
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Review carousel ────────────────────────────────────────────────────────
function ReviewCarousel() {
  const [i, setI] = useState(0);
  const n = REVIEWS.length;
  useEffect(() => {
    const t = setInterval(() => setI(x => (x+1) % n), 7000);
    return () => clearInterval(t);
  }, [n]);
  const r = REVIEWS[i];
  return (
    <div className="relative">
      <div className="text-teal/15 text-[180px] md:text-[260px] leading-none absolute -top-10 -left-3 select-none pointer-events-none" style={{ fontFamily: 'Fraunces', fontStyle: 'italic', fontWeight: 300 }}>"</div>
      <div className="relative min-h-[200px]">
        <blockquote className="font-display text-[28px] md:text-[40px] max-w-[24ch]">
          {r.quote}
        </blockquote>
        <div className="mt-6 flex items-center gap-5">
          <div className="flex items-center gap-2.5">
            <div className="w-8 h-8 rounded-full bg-sand-deep/70 flex items-center justify-center font-display text-teal-dark font-semibold">
              {r.author[0]}
            </div>
            <div className="leading-tight">
              <div className="text-[13px] text-ink">{r.author}, {r.origin}</div>
              <div className="mono text-[10.5px] ink-soft tracking-[0.08em]">{r.nights} nights · {r.apartment} · {r.source}</div>
            </div>
          </div>
        </div>
      </div>
      <div className="mt-8 flex items-center gap-2">
        {REVIEWS.map((_, k) => (
          <button key={k} aria-label={`Review ${k+1}`} onClick={() => setI(k)} className={`h-[2px] transition-all ${k===i ? 'w-10 bg-teal' : 'w-5 bg-ink/20 hover:bg-ink/40'}`}/>
        ))}
      </div>
    </div>
  );
}

// ─── Map embed (Tecom) — schematic, not a real Google map ───────────────────
function MapEmbed() {
  const pins = [
    { x: 50, y: 50, label: 'Gulf Oasis',         type: 'self',    important: true },
    { x: 36, y: 62, label: 'Internet City Metro', type: 'metro' },
    { x: 54, y: 47, label: 'Carrefour Express',   type: 'grocery' },
    { x: 47, y: 53, label: 'Subway',              type: 'food' },
    { x: 22, y: 30, label: 'Mall of the Emirates', type: 'mall' },
    { x: 24, y: 27, label: 'Ski Dubai',           type: 'leisure' },
    { x: 78, y: 36, label: 'Dubai Marina',        type: 'leisure' },
    { x: 82, y: 41, label: 'JBR',                 type: 'leisure' },
    { x: 40, y: 60, label: 'Internet City',       type: 'work' },
    { x: 42, y: 68, label: 'Media City',          type: 'work' },
  ];
  const [hover, setHover] = useState(null);
  return (
    <div className="relative aspect-[16/10] bg-sand/60 border hairline overflow-hidden">
      {/* Grid */}
      <svg className="absolute inset-0 w-full h-full opacity-[0.18]" preserveAspectRatio="none" viewBox="0 0 100 100">
        {[...Array(11)].map((_, i) => (<line key={'v'+i} x1={i*10} y1="0" x2={i*10} y2="100" stroke="currentColor" strokeWidth="0.1" className="text-teal"/>))}
        {[...Array(11)].map((_, i) => (<line key={'h'+i} x1="0" y1={i*10} x2="100" y2={i*10} stroke="currentColor" strokeWidth="0.1" className="text-teal"/>))}
      </svg>
      {/* Metro line */}
      <svg className="absolute inset-0 w-full h-full" preserveAspectRatio="none" viewBox="0 0 100 100">
        <path d="M 5 70 Q 30 64 50 50 T 95 25" fill="none" stroke="currentColor" strokeWidth="0.5" strokeDasharray="1 1.2" className="text-teal/60"/>
        <path d="M 5 78 Q 35 75 55 60" fill="none" stroke="currentColor" strokeWidth="0.5" strokeDasharray="1 1.2" className="text-walnut/50"/>
      </svg>
      {/* Pins */}
      {pins.map((p, i) => (
        <div key={i}
             onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}
             className="absolute -translate-x-1/2 -translate-y-1/2"
             style={{ left: `${p.x}%`, top: `${p.y}%` }}>
          <div className={`relative flex items-center gap-1.5 ${p.important ? '' : ''}`}>
            <span className={`block ${p.important ? 'w-3 h-3 bg-teal ring-4 ring-teal/20' : 'w-2 h-2 bg-walnut'} rounded-full`}></span>
            <span className={`mono text-[10.5px] ${p.important ? 'text-teal font-medium' : 'text-walnut'} whitespace-nowrap`}>{p.label}</span>
          </div>
          {p.important && (
            <div className="absolute left-1/2 -translate-x-1/2 -bottom-7 mono text-[9.5px] tracking-[0.16em] uppercase text-teal/80">25.0939, 55.1770</div>
          )}
        </div>
      ))}
      {/* Compass */}
      <div className="absolute top-4 right-4 mono text-[10px] text-walnut/70">
        <div className="text-center mb-0.5">N</div>
        <div className="w-px h-6 bg-walnut/50 mx-auto"></div>
      </div>
      <div className="absolute bottom-4 left-4 mono text-[10px] tracking-[0.16em] uppercase text-walnut/70">
        Barsha Heights · Tecom · Dubai
      </div>
      <a
        href="https://www.google.com/maps/search/?api=1&query=Gulf+Oasis+Hotel+Apartments+Barsha+Heights+Tecom+Dubai"
        target="_blank"
        rel="noreferrer"
        className="absolute bottom-4 right-4 bg-cream text-teal border hairline px-3 py-2 mono text-[10px] tracking-[0.14em] uppercase hover:bg-teal hover:text-cream transition-colors">
        Open Google Maps
      </a>
    </div>
  );
}

// ─── WhatsApp FAB ───────────────────────────────────────────────────────────
function WhatsAppFab() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(o => !o)}
              className="fixed bottom-5 right-5 z-30 w-14 h-14 rounded-full bg-[#25D366] text-white shadow-lg flex items-center justify-center hover:scale-105 transition"
              aria-label="WhatsApp">
        <Icon name="whatsapp" className="w-7 h-7"/>
      </button>
      {open && (
        <div className="fixed bottom-24 right-5 z-30 w-[280px] bg-cream border hairline shadow-xl p-4">
          <div className="mono text-[10px] tracking-[0.2em] uppercase ink-soft mb-1">WhatsApp · reception</div>
          <div className="font-display text-[18px] leading-snug">We answer in &lt;5 minutes, 24/7.</div>
          <a href="https://wa.me/97144517111" className="mt-3 inline-flex items-center gap-2 px-3.5 py-2 bg-[#25D366] text-white text-[13px] rounded">
            <Icon name="whatsapp" className="w-4 h-4"/> +971 4 451 7111
          </a>
        </div>
      )}
    </>
  );
}

// ─── Section header ─────────────────────────────────────────────────────────
function SectionLabel({ index, eyebrow, children, sub }) {
  return (
    <div className="flex flex-col gap-4">
      <div className="flex items-baseline gap-3">
        <span className="num text-teal text-[26px]">{index}</span>
        <span className="mono text-[10.5px] tracking-[0.22em] uppercase ink-soft">{eyebrow}</span>
      </div>
      <h2 className="font-display text-[40px] md:text-[64px] max-w-[18ch]">
        {children}
      </h2>
      {sub && <p className="text-[15.5px] md:text-[17px] text-ink-soft max-w-[55ch] leading-snug">{sub}</p>}
    </div>
  );
}

// ─── Footer ─────────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer className="border-t hairline mt-24">
      <div className="max-w-[1320px] mx-auto px-6 md:px-10 py-16 grid md:grid-cols-12 gap-10">
        <div className="md:col-span-4">
          <Logo />
          <p className="mt-5 text-[14px] text-ink-soft leading-snug max-w-[40ch]">
            An independent 4-star aparthotel in Barsha Heights — 159 fully-fitted apartments, full kitchens, in-unit laundry, and a rate that gets better the longer you stay.
          </p>
          <div className="mt-5 mono text-[10.5px] tracking-[0.12em] ink-soft">
            Dubai Tourism licence 18841 · Gulf Oasis Hotel Apartments Fz LLC
          </div>
        </div>
        <div className="md:col-span-3">
          <div className="mono text-[10px] tracking-[0.2em] uppercase ink-soft mb-3">Visit</div>
          <ul className="space-y-1.5 text-[13.5px]">
            <li>Barsha Heights (Tecom)</li>
            <li>Dubai, UAE</li>
            <li className="num text-teal text-[14px]">25.0939, 55.1770</li>
          </ul>
        </div>
        <div className="md:col-span-2">
          <div className="mono text-[10px] tracking-[0.2em] uppercase ink-soft mb-3">Speak to us</div>
          <ul className="space-y-1.5 text-[13.5px]">
            <li><a href="tel:+97144517111" className="hover:text-teal">+971 4 451 7111</a></li>
            <li><a href="https://wa.me/97144517111" className="hover:text-teal">WhatsApp 24/7</a></li>
            <li><a href="mailto:reservations@gulfoasishotelapartments.com" className="hover:text-teal">reservations@</a></li>
          </ul>
        </div>
        <div className="md:col-span-3">
          <div className="mono text-[10px] tracking-[0.2em] uppercase ink-soft mb-3">Direct-book benefits</div>
          <ul className="space-y-1.5 text-[13.5px]">
            <li className="flex items-center gap-1.5"><Icon name="check" className="w-3.5 h-3.5 text-teal"/> Best rate, no commission</li>
            <li className="flex items-center gap-1.5"><Icon name="check" className="w-3.5 h-3.5 text-teal"/> Free 48h cancellation</li>
            <li className="flex items-center gap-1.5"><Icon name="check" className="w-3.5 h-3.5 text-teal"/> Free late checkout (7+ nights)</li>
            <li className="flex items-center gap-1.5"><Icon name="check" className="w-3.5 h-3.5 text-teal"/> Welcome shop on arrival</li>
          </ul>
        </div>
      </div>
      <div className="border-t hairline">
        <div className="max-w-[1320px] mx-auto px-6 md:px-10 py-6 flex flex-wrap items-center justify-between gap-4 mono text-[10.5px] tracking-[0.06em] ink-soft">
          <div>© 2026 Gulf Oasis Hotel Apartments · gulfoasishotelapartments.com</div>
          <div className="flex gap-5">
            <a href="#" className="hover:text-ink">Privacy</a>
            <a href="#" className="hover:text-ink">Cookies</a>
            <a href="#" className="hover:text-ink">Sitemap</a>
            <a href="#" className="hover:text-ink">Accessibility</a>
          </div>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Icon, Stat, Placeholder, Logo, Navbar,
  BookingWidget, ApartmentCard, ComparisonTable,
  ReviewBadges, ReviewCarousel, MapEmbed, WhatsAppFab,
  SectionLabel, Footer,
});
