// Smaller reusable components. Loaded as Babel script.
// Globals expected: React, COPY.

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

// ── Icon glyphs (small inline SVGs) ─────────────────────────────────────────
function Icon({ name, size = 16, stroke = 'currentColor' }) {
  const s = { width: size, height: size, fill: 'none', stroke, strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'arrow-right': return <svg viewBox="0 0 24 24" {...s}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case 'arrow-down': return <svg viewBox="0 0 24 24" {...s}><path d="M12 5v14M5 13l7 7 7-7"/></svg>;
    case 'chevron': return <svg viewBox="0 0 24 24" {...s}><path d="M6 9l6 6 6-6"/></svg>;
    case 'close': return <svg viewBox="0 0 24 24" {...s}><path d="M6 6l12 12M18 6L6 18"/></svg>;
    case 'whatsapp': return (
      <svg viewBox="0 0 24 24" width={size} height={size}>
        <path fill="currentColor" d="M17.4 14.4c-.3-.1-1.7-.8-2-.9-.3-.1-.5-.2-.6.2s-.7.9-.9 1.1c-.2.2-.3.2-.6.1-.3-.1-1.2-.5-2.3-1.5-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.6-1.5-.9-2.1-.2-.5-.5-.5-.6-.5h-.6c-.2 0-.5.1-.7.3-.2.3-1 .9-1 2.3s1 2.7 1.1 2.9c.2.2 2.1 3.1 5 4.4.7.3 1.3.5 1.7.6.7.2 1.3.2 1.8.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.2.2-1.4-.1-.2-.3-.3-.6-.4z"/>
        <path fill="currentColor" d="M12 2C6.5 2 2 6.5 2 12c0 1.9.5 3.7 1.5 5.3L2 22l4.9-1.5c1.5.8 3.3 1.3 5.1 1.3 5.5 0 10-4.5 10-10S17.5 2 12 2zm0 18c-1.7 0-3.3-.5-4.7-1.3l-.3-.2-3.4 1 1-3.3-.2-.3C3.5 14.6 3 13.3 3 12c0-5 4-9 9-9s9 4 9 9-4 9-9 9z"/>
      </svg>
    );
    case 'phone': return <svg viewBox="0 0 24 24" {...s}><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3-8.7A2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.3 1.8.6 2.6a2 2 0 0 1-.5 2.1L8 9.6a16 16 0 0 0 6 6l1.2-1.3a2 2 0 0 1 2.1-.5c.8.3 1.7.5 2.6.6a2 2 0 0 1 1.7 2z"/></svg>;
    case 'mail': return <svg viewBox="0 0 24 24" {...s}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>;
    case 'pin': return <svg viewBox="0 0 24 24" {...s}><path d="M12 21s7-6.5 7-12a7 7 0 0 0-14 0c0 5.5 7 12 7 12z"/><circle cx="12" cy="9" r="2.5"/></svg>;
    case 'check': return <svg viewBox="0 0 24 24" {...s}><path d="M5 12l5 5 9-11"/></svg>;
    case 'plus': return <svg viewBox="0 0 24 24" {...s}><path d="M12 5v14M5 12h14"/></svg>;
    case 'globe': return <svg viewBox="0 0 24 24" {...s}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></svg>;
    default: return null;
  }
}

// ── Hairline + numeric label ────────────────────────────────────────────────
function SectionHeader({ number, eyebrow, heading, className = '' }) {
  return (
    <div className={`sect-head ${className}`}>
      <div className="sect-meta">
        <span className="sect-num">{number}</span>
        <span className="hairline" aria-hidden="true"></span>
        <span className="sect-eye">{eyebrow}</span>
      </div>
      <h2 className="sect-h">{heading}</h2>
    </div>
  );
}

// ── Animated count-up ───────────────────────────────────────────────────────
function CountUp({ target, duration = 1400 }) {
  const ref = useRef(null);
  const [val, setVal] = useState(target);
  const [started, setStarted] = useState(false);

  // Parse leading number portion (e.g. "24.7M" -> 24.7, "M"). Strings without
  // a leading number are passed through.
  const m = String(target).match(/^([\d.,]+)(.*)$/);
  const numeric = m ? parseFloat(m[1].replace(/,/g, '')) : null;
  const suffix = m ? m[2] : '';

  useEffect(() => {
    if (numeric === null) return;
    const el = ref.current;
    if (!el) return;
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting && !started) setStarted(true); });
    }, { threshold: 0.4 });
    obs.observe(el);
    return () => obs.disconnect();
  }, [numeric, started]);

  useEffect(() => {
    if (!started || numeric === null) return;
    const t0 = performance.now();
    let raf;
    const tick = (t) => {
      const k = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - k, 3);
      const cur = numeric * eased;
      const formatted = cur >= 100 ? Math.round(cur).toLocaleString() : cur.toFixed(1);
      setVal(formatted + suffix);
      if (k < 1) raf = requestAnimationFrame(tick);
      else setVal(target); // ensure final exact text
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [started, numeric, duration, target, suffix]);

  return <span ref={ref}>{numeric === null ? target : val}</span>;
}

// ── Nav (sticky, transparent → solid on scroll) ─────────────────────────────
function Nav({ locale, setLocale, onRegister, dir }) {
  const t = COPY[locale] || COPY.en;
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const [langOpen, setLangOpen] = useState(false);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 40);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const items = [
    ['overview', t.nav.overview],
    ['residences', t.nav.residences],
    ['amenities', t.nav.amenities],
    ['gallery', t.nav.gallery],
    ['location', t.nav.location],
    ['provenance', t.nav.provenance],
  ];

  return (
    <nav className={`nav ${scrolled ? 'nav--solid' : ''}`} dir={dir}>
      <a className="nav-brand" href="#top" onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }}>
        <img src="media/logo-select-group-white.svg" alt="Select Group" className="nav-logo nav-logo--dark" />
        <img src="media/logo-select-group.svg" alt="Select Group" className="nav-logo nav-logo--light" />
      </a>
      <ul className="nav-items">
        {items.map(([id, label]) => (
          <li key={id}><a href={`#${id}`} onClick={(e) => {
            e.preventDefault();
            const el = document.getElementById(id);
            if (el) window.scrollTo({ top: el.offsetTop - 64, behavior: 'smooth' });
          }}>{label}</a></li>
        ))}
      </ul>
      <div className="nav-right">
        <div className="lang">
          <button className="lang-btn" onClick={() => setLangOpen(!langOpen)} aria-expanded={langOpen}>
            <Icon name="globe" size={14} />
            <span>{locale.toUpperCase()}</span>
            <Icon name="chevron" size={12} />
          </button>
          {langOpen && (
            <div className="lang-menu" onMouseLeave={() => setLangOpen(false)}>
              {Object.entries(t.locales).map(([k, v]) => (
                <button key={k} className={k === locale ? 'is-on' : ''} onClick={() => { setLocale(k); setLangOpen(false); }}>
                  <span>{v}</span>
                  {COPY[k] && COPY[k]._partial && <em>preview</em>}
                </button>
              ))}
            </div>
          )}
        </div>
        <button className="btn btn--primary nav-cta" onClick={onRegister}>
          {t.nav.register}
          <Icon name="arrow-right" size={14} />
        </button>
        <button className="nav-burger" onClick={() => setOpen(!open)} aria-label="Menu">
          <span></span><span></span><span></span>
        </button>
      </div>
      {open && (
        <div className="nav-drawer" onClick={() => setOpen(false)}>
          <ul>
            {items.map(([id, label]) => (
              <li key={id}><a href={`#${id}`}>{label}</a></li>
            ))}
          </ul>
        </div>
      )}
    </nav>
  );
}

// ── Phone with international code prefix ────────────────────────────────────
function PhoneField({ value, onChange, label, dir }) {
  const [code, setCode] = useState('+971');
  const [num, setNum] = useState(value || '');
  const codes = ['+971', '+44', '+1', '+7', '+86', '+33', '+49', '+966', '+974', '+965'];
  useEffect(() => { onChange?.(`${code} ${num}`); }, [code, num]);
  return (
    <label className="field">
      <span className="field-lbl">{label}</span>
      <div className="phone-wrap">
        <select value={code} onChange={(e) => setCode(e.target.value)} className="phone-code">
          {codes.map((c) => <option key={c}>{c}</option>)}
        </select>
        <input type="tel" inputMode="tel" value={num} onChange={(e) => setNum(e.target.value)} placeholder="50 000 0000" />
      </div>
    </label>
  );
}

// ── Register Interest form ──────────────────────────────────────────────────
function RegisterForm({ locale, presetResidence, onSent }) {
  const t = COPY[locale] || COPY.en;
  const f = (t.convert && t.convert.fields) || COPY.en.convert.fields;
  const sent = (t.convert && t.convert.sent) || COPY.en.convert.sent;
  const submit = f.submit;

  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [country, setCountry] = useState('');
  const [residence, setResidence] = useState(presetResidence || (f.residenceOpt && f.residenceOpt[0]) || '');
  const [timeline, setTimeline] = useState((f.timelineOpt && f.timelineOpt[0]) || '');
  const [message, setMessage] = useState('');
  const [consent, setConsent] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [errors, setErrors] = useState({});

  const validate = () => {
    const e = {};
    if (!name || name.trim().length < 2) e.name = true;
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = true;
    if (!phone || phone.replace(/\D/g, '').length < 6) e.phone = true;
    if (!consent) e.consent = true;
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const onSubmit = (e) => {
    e.preventDefault();
    if (!validate()) return;
    setSubmitted(true);
    onSent?.({ kind: 'register', name, email, phone, country, residence, timeline, message, locale });
  };

  if (submitted) {
    return (
      <div className="form form--sent">
        <div className="sent-mark"><Icon name="check" size={28} /></div>
        <p className="sent-msg">{sent}</p>
        <p className="sent-meta">Ref · SSM-{Date.now().toString().slice(-6)}</p>
      </div>
    );
  }

  return (
    <form className="form" onSubmit={onSubmit} noValidate>
      <div className="form-grid">
        <label className={`field field--full ${errors.name ? 'is-err' : ''}`}>
          <span className="field-lbl">{f.name}</span>
          <input value={name} onChange={(e) => setName(e.target.value)} autoComplete="name" />
        </label>
        <label className={`field ${errors.email ? 'is-err' : ''}`}>
          <span className="field-lbl">{f.email}</span>
          <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} autoComplete="email" />
        </label>
        <div className={`field ${errors.phone ? 'is-err' : ''}`}>
          <PhoneField label={f.phone} value={phone} onChange={setPhone} />
        </div>
        <label className="field">
          <span className="field-lbl">{f.country}</span>
          <input value={country} onChange={(e) => setCountry(e.target.value)} placeholder="UAE" />
        </label>
        <label className="field">
          <span className="field-lbl">{f.residence}</span>
          <div className="select-wrap">
            <select value={residence} onChange={(e) => setResidence(e.target.value)}>
              {(f.residenceOpt || []).map((o) => <option key={o}>{o}</option>)}
            </select>
            <Icon name="chevron" size={14} />
          </div>
        </label>
        <label className="field field--full">
          <span className="field-lbl">{f.timeline}</span>
          <div className="seg">
            {(f.timelineOpt || []).map((o) => (
              <button type="button" key={o} className={timeline === o ? 'is-on' : ''} onClick={() => setTimeline(o)}>{o}</button>
            ))}
          </div>
        </label>
        <label className="field field--full">
          <span className="field-lbl">{f.message}</span>
          <textarea rows={3} value={message} onChange={(e) => setMessage(e.target.value)} />
        </label>
      </div>
      <label className={`consent ${errors.consent ? 'is-err' : ''}`}>
        <input type="checkbox" checked={consent} onChange={(e) => setConsent(e.target.checked)} />
        <span>{f.consent}</span>
      </label>
      <button type="submit" className="btn btn--primary btn--lg">
        {submit}
        <Icon name="arrow-right" size={14} />
      </button>
    </form>
  );
}

// ── Modal (private viewing / brochure gate) ─────────────────────────────────
function Modal({ open, onClose, kind, locale }) {
  const t = COPY[locale] || COPY.en;
  const m = (t.modal || COPY.en.modal);
  const f = (t.convert && t.convert.fields) || COPY.en.convert.fields;

  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [date, setDate] = useState('');
  const [time, setTime] = useState('10:00');
  const [where, setWhere] = useState(m.locOpt[0]);
  const [sent, setSent] = useState(false);

  useEffect(() => {
    if (open) { setSent(false); document.body.style.overflow = 'hidden'; }
    else document.body.style.overflow = '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  if (!open) return null;
  const isViewing = kind === 'viewing';
  const isBroker = kind === 'broker';
  const title = isViewing ? m.titleViewing : isBroker ? m.titleBroker : m.titleBrochure;
  const submit = isViewing ? m.submit : m.submitBrochure;
  const sentMsg = isViewing ? ((t.convert && t.convert.sentViewing) || COPY.en.convert.sentViewing) : ((t.convert && t.convert.sentBrochure) || COPY.en.convert.sentBrochure);

  const doSubmit = (e) => {
    e.preventDefault();
    setSent(true);
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose} aria-label={m.close}><Icon name="close" size={18} /></button>
        <div className="modal-side">
          <div className="modal-mark"><img src="media/logo-select-group-white.svg" alt="" /></div>
          <p className="modal-eye">Six Senses Residences · Dubai Marina</p>
          <h3 className="modal-h">{title}</h3>
          <p className="modal-sub">{(t.convert && t.convert.body) || COPY.en.convert.body}</p>
          <div className="modal-meta">
            <div><span>Tel</span><b>+971 4 368 3355</b></div>
            <div><span>WhatsApp</span><b>+971 52 459 6183</b></div>
            <div><span>HQ</span><b>Peninsula, Business Bay</b></div>
          </div>
        </div>
        <div className="modal-body">
          {sent ? (
            <div className="form form--sent" style={{ minHeight: 260 }}>
              <div className="sent-mark"><Icon name="check" size={28} /></div>
              <p className="sent-msg">{sentMsg}</p>
              <button type="button" className="btn btn--ghost" onClick={onClose}>{m.close}</button>
            </div>
          ) : (
            <form className="form" onSubmit={doSubmit}>
              <div className="form-grid">
                <label className="field field--full">
                  <span className="field-lbl">{f.name}</span>
                  <input value={name} onChange={(e) => setName(e.target.value)} required />
                </label>
                <label className="field">
                  <span className="field-lbl">{f.email}</span>
                  <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
                </label>
                <div className="field"><PhoneField label={f.phone} value={phone} onChange={setPhone} /></div>
                {isViewing && (
                  <>
                    <label className="field">
                      <span className="field-lbl">{m.labelDate}</span>
                      <input type="date" value={date} onChange={(e) => setDate(e.target.value)} required />
                    </label>
                    <label className="field">
                      <span className="field-lbl">{m.labelTime}</span>
                      <input type="time" value={time} onChange={(e) => setTime(e.target.value)} required />
                    </label>
                    <label className="field field--full">
                      <span className="field-lbl">{m.labelLocation}</span>
                      <div className="select-wrap">
                        <select value={where} onChange={(e) => setWhere(e.target.value)}>
                          {m.locOpt.map((o) => <option key={o}>{o}</option>)}
                        </select>
                        <Icon name="chevron" size={14} />
                      </div>
                    </label>
                  </>
                )}
              </div>
              <button className="btn btn--primary btn--lg" type="submit">
                {submit}
                <Icon name="arrow-right" size={14} />
              </button>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}

// ── WhatsApp floating button ────────────────────────────────────────────────
function WhatsAppFab({ dir }) {
  const [shown, setShown] = useState(false);
  useEffect(() => { const t = setTimeout(() => setShown(true), 1200); return () => clearTimeout(t); }, []);
  return (
    <a className={`fab ${shown ? 'is-shown' : ''}`} href="https://wa.me/971524596183" target="_blank" rel="noopener" aria-label="WhatsApp +971 52 459 6183" data-dir={dir}>
      <Icon name="whatsapp" size={22} />
      <span className="fab-label">+971 52 459 6183</span>
    </a>
  );
}

// ── Mobile sticky CTA ───────────────────────────────────────────────────────
function MobileBar({ locale, onRegister, onViewing }) {
  const t = COPY[locale] || COPY.en;
  return (
    <div className="mbar">
      <a className="mbar-icon" href="tel:+97143683355" aria-label="Call"><Icon name="phone" size={18} /></a>
      <a className="mbar-icon" href="https://wa.me/971524596183" target="_blank" rel="noopener" aria-label="WhatsApp"><Icon name="whatsapp" size={18} /></a>
      <button className="mbar-cta" onClick={onRegister}>
        {(t.nav && t.nav.register) || 'Register Interest'}
      </button>
    </div>
  );
}

// ── Footer ──────────────────────────────────────────────────────────────────
function Footer({ locale }) {
  const t = COPY[locale] || COPY.en;
  const f = t.footer || COPY.en.footer;
  return (
    <footer className="footer">
      <div className="wrap footer-grid">
        <div className="footer-brand">
          <img src="media/logo-select-group-white.svg" alt="Select Group" />
          <p className="footer-tag">{(t.hero && t.hero.tagline) || COPY.en.hero.tagline}</p>
        </div>
        <div>
          <h6>Contact</h6>
          <ul className="footer-list">
            <li><a href="tel:+97143683355">{f.phone}</a></li>
            <li><a href="tel:800100001">{f.tollfree}</a></li>
            <li><a href="https://wa.me/971524596183">WhatsApp · {f.whatsapp}</a></li>
            <li><a href={`mailto:${f.email}`}>{f.email}</a></li>
            <li><a href="#">{f.customerCare}</a></li>
          </ul>
        </div>
        <div>
          <h6>Address</h6>
          <ul className="footer-list">
            <li>{f.address}</li>
            <li>{f.address2}</li>
            <li>{f.pobox}</li>
            <li className="muted">{f.hours} <em>{f.hoursNote}</em></li>
          </ul>
        </div>
        <div>
          <h6>Follow</h6>
          <ul className="footer-list">
            <li><a href="https://instagram.com/selectgroupuae" target="_blank" rel="noopener">Instagram · @selectgroupuae</a></li>
            <li><a href="https://facebook.com/selectgroupuae" target="_blank" rel="noopener">Facebook · @selectgroupuae</a></li>
            <li><a href="https://x.com/selectgroupuae" target="_blank" rel="noopener">X · @selectgroupuae</a></li>
            <li><a href="https://linkedin.com/company/dubai-select-llc" target="_blank" rel="noopener">LinkedIn · /dubai-select-llc</a></li>
            <li><a href="#" target="_blank" rel="noopener">YouTube</a></li>
          </ul>
        </div>
      </div>
      <div className="wrap footer-base">
        <p className="footer-disc">{f.disclaimer}</p>
        <div className="footer-meta">
          <span>{f.copyright}</span>
          <ul>{f.legal.map((l) => <li key={l}><a href="#">{l}</a></li>)}</ul>
        </div>
      </div>
    </footer>
  );
}

// Export to window for cross-script use
Object.assign(window, {
  Icon, SectionHeader, CountUp, Nav,
  RegisterForm, Modal, WhatsAppFab, MobileBar, Footer, PhoneField,
});
