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

// ===================== i18n context =====================
const LocaleContext = React.createContext({ locale: "nl", setLocale: () => {} });
function useLoc() { return React.useContext(LocaleContext); }
function useT() {
  const { locale } = useLoc();
  return useCallback((k) => window.YV_I18N.read(k, locale), [locale]);
}

// ===================== Language toggle =====================
function LangToggle() {
  const { locale, setLocale } = useLoc();
  const t = useT();
  return (
    <div className="lang-toggle" role="group" aria-label={t("lang.label")}>
      <button type="button" aria-pressed={locale === "nl"} onClick={() => setLocale("nl")}>{t("lang.nl")}</button>
      <span aria-hidden="true" className="lang-sep">/</span>
      <button type="button" aria-pressed={locale === "en"} onClick={() => setLocale("en")}>{t("lang.en")}</button>
    </div>
  );
}

// ===================== Nav =====================
function Nav() {
  const t = useT();
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <header className="nav" data-scrolled={scrolled || undefined}>
      <div className="container nav-inner">
        <a href="#top" className="brand" aria-label="Yogavibe Reviews">
          <span className="brand-logo" role="img" aria-hidden="true"></span>
          <span className="brand-wordmark">Yogavibe</span>
          <span className="brand-suffix">Reviews</span>
        </a>
        <nav className="nav-links" aria-label="primary">
          <a href="#all-reviews">{t("nav.reviews")}</a>
          <a href="#leave-review">{t("nav.leave")}</a>
          <a href="#faq" className="hide-sm">{t("nav.faq")}</a>
          <a href="https://yogavibe.eu" className="hide-sm" target="_blank" rel="noopener">
            <span className="loc">Yogavibe.eu</span>
          </a>
          <LangToggle />
        </nav>
      </div>
    </header>
  );
}

// ===================== Hero =====================
function Hero({ stats }) {
  const t = useT();
  const { locale } = useLoc();
  return (
    <section className="hero container" id="top">
      <div className="hero-eyebrow-row reveal">
        <span className="eyebrow">{t("hero.eyebrow")}</span>
        <span className="caption" style={{ color: "var(--ink-mute)" }}>{t("hero.est")}</span>
      </div>

      <div className="hero-grid">
        <div className="hero-text-col">
          <h1 className="hero-headline reveal">
            {t("hero.h1l1")}<br/>
            <i>{t("hero.h1em")}</i>
            {t("hero.h1l2") ? <React.Fragment><br/>{t("hero.h1l2")}</React.Fragment> : null}
          </h1>
          <div className="hero-side reveal">
            <p className="lead">{t("hero.lead")}</p>
            <div className="hero-cta-row">
              <a href="#all-reviews" className="btn btn-primary btn-arrow">
                {t("hero.ctaRead")} <IconArrow />
              </a>
              <a href="#leave-review" className="btn btn-ghost">
                {t("hero.ctaShare")}
              </a>
            </div>
          </div>
        </div>

        <figure className="hero-photo reveal">
          <img src="images/yoga-class.jpg" alt="Morning yoga class on the riad terrace in Essaouira" loading="eager" fetchpriority="high" width="1344" height="1682" />
          <figcaption>{t("hero.photoCap")}</figcaption>
        </figure>
      </div>

      <div className="hero-stats reveal" style={{ marginTop: "clamp(36px, 5vw, 72px)" }}>
        <div>
          <div className="hero-rating-num">
            {stats.avg.toFixed(1)}<small>/5</small>
          </div>
        </div>
        <div>
          <Stars rating={stats.avg} size="lg" />
          <div className="hero-rating-meta" style={{ marginTop: 10 }}>
            {t("hero.basedOnPre")} <strong>{stats.total} {t("hero.verifiedReviews")}</strong> &nbsp;·&nbsp;
            {stats.fiveStarPct}% {t("hero.fiveStars")}
          </div>
          <div className="caption" style={{ marginTop: 4, display: "flex", gap: 14, flexWrap: "wrap", alignItems: "center" }}>
            <span>{t("hero.lastUpdated")} · {formatDate(stats.lastDate, locale)}</span>
            <a
              href="https://www.trustpilot.com/review/yogavibe.eu"
              target="_blank"
              rel="noopener"
              style={{ color: "var(--ink)", borderBottom: "1px solid var(--ink)", paddingBottom: 1, display: "inline-flex", gap: 6, alignItems: "center" }}
            >
              {t("hero.verify")} <IconArrow style={{ transform: "rotate(-45deg)" }} />
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

// ===================== Marquee =====================
function Marquee() {
  const t = useT();
  const items = t("marquee") || [];
  const row = (key) => (
    <span key={key}>
      {items.map((txt, i) => (
        <React.Fragment key={i}>
          <i>{txt}</i>
          <span className="dot" aria-hidden="true"></span>
        </React.Fragment>
      ))}
    </span>
  );
  return (
    <div className="marquee" aria-hidden="true">
      <div className="marquee-track">
        {row("a")}
        {row("b")}
      </div>
    </div>
  );
}

// ===================== Glimpses gallery =====================
function Glimpses() {
  const t = useT();
  const caps = t("glimpses.captions") || {};
  const photos = [
    { src: "images/surf-class.jpg",        alt: "Six guests on surfboards practising on Sidi Kaouki beach",       cols: 7, rows: 1 },
    { src: "images/dunes-group.jpg",       alt: "Group of guests posing on a sand dune above the Atlantic",       cols: 5, rows: 2 },
    { src: "images/riad-lunch.jpg",        alt: "Long lunch under stone arches at the riad in Essaouira",         cols: 4, rows: 1 },
    { src: "images/horseback.jpg",         alt: "Three guests on horseback riding through coastal scrubland",     cols: 3, rows: 1 },
    { src: "images/garden-meditation.jpg", alt: "Seated meditation in the garden, framed by palm fronds",         cols: 6, rows: 1 },
    { src: "images/pool-friends.jpg",      alt: "Seven guests in the riad pool, smiling",                         cols: 6, rows: 1 },
  ];

  return (
    <section className="section-tight container" aria-label="Glimpses from the retreats">
      <div className="reveal glimpses-head">
        <span className="eyebrow">{t("glimpses.eyebrow")}</span>
        <h2 className="h2" style={{ marginTop: 16, maxWidth: 720 }}>
          {t("glimpses.h2l1")} <i>{t("glimpses.h2em")}</i>
        </h2>
      </div>

      <div className="glimpses-grid">
        {photos.map((p) => (
          <figure
            key={p.src}
            className="glimpse reveal"
            style={{ gridColumn: `span ${p.cols}`, gridRow: `span ${p.rows}` }}
          >
            <img src={p.src} alt={p.alt} loading="lazy" />
            <figcaption>{caps[p.src] || ""}</figcaption>
          </figure>
        ))}
      </div>
    </section>
  );
}

// ===================== Review card =====================
function ReviewCard({ r }) {
  const t = useT();
  const { locale } = useLoc();
  const [expanded, setExpanded] = useState(false);
  const long = (r.body || "").length > 380;
  return (
    <article className="review" itemScope itemType="https://schema.org/Review" lang={r.language || undefined}>
      <meta itemProp="itemReviewed" content="Yogavibe" />
      <meta itemProp="author" content={r.name} />
      <meta itemProp="datePublished" content={r.date} />
      <div itemProp="reviewRating" itemScope itemType="https://schema.org/Rating">
        <meta itemProp="ratingValue" content={String(r.rating)} />
        <meta itemProp="bestRating" content="5" />
      </div>

      <div className="review-head">
        <Avatar initials={r.initials} seed={r.id} />
        <div>
          <div className="reviewer-name">{r.name}</div>
          <div className="reviewer-meta">
            {r.country ? `${r.country} · ` : ""}
            {r.reviewCount ? `${r.reviewCount} ${r.reviewCount === 1 ? t("review.one") : t("review.many")}` : `1 ${t("review.one")}`}
          </div>
        </div>
        <SourceBadge source={r.source} />
      </div>

      <div className="review-rating-row">
        <Stars rating={r.rating} />
      </div>

      <h3 className="review-title" itemProp="name">{r.title}</h3>
      <p className={`review-body ${long && !expanded ? "clamped" : ""}`} itemProp="reviewBody">
        {r.body}
      </p>
      {long && (
        <button className="review-readmore" onClick={() => setExpanded((e) => !e)}>
          {expanded ? t("review.showLess") : t("review.readMore")}
        </button>
      )}

      <div className="review-foot">
        <span>{formatDate(r.date, locale)}</span>
        {r.location && <span className="review-loc">{r.location}</span>}
      </div>
    </article>
  );
}

// ===================== Filters + feed =====================
function ReviewsFeed({ reviews }) {
  const t = useT();
  const [rating, setRating] = useState("all");
  const [sort, setSort] = useState("highest");
  const [shown, setShown] = useState(9);

  const filtered = useMemo(() => {
    let list = reviews.slice();
    if (rating !== "all") list = list.filter((r) => r.rating === Number(rating));
    if (sort === "recent") list.sort((a, b) => new Date(b.date) - new Date(a.date));
    if (sort === "oldest") list.sort((a, b) => new Date(a.date) - new Date(b.date));
    if (sort === "highest") list.sort((a, b) => b.rating - a.rating || new Date(b.date) - new Date(a.date));
    if (sort === "lowest") list.sort((a, b) => a.rating - b.rating || new Date(b.date) - new Date(a.date));
    return list;
  }, [reviews, rating, sort]);

  useEffect(() => { setShown(9); }, [rating, sort]);

  return (
    <section className="section container" id="all-reviews">
      <div className="reveal" style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 24, marginBottom: 40 }}>
        <div>
          <span className="eyebrow">{t("feed.eyebrowPre")} · {filtered.length} {t("feed.of")} {reviews.length}</span>
          <h2 className="h1" style={{ marginTop: 18, maxWidth: 720 }}>
            {t("feed.h2l1")} <i>{t("feed.h2em")}</i>{t("feed.h2l2")}
          </h2>
        </div>
        <p className="lead" style={{ maxWidth: 360 }}>
          {t("feed.lead")}
        </p>
      </div>

      <div className="filter-bar reveal">
        <div className="filter-chips" role="group" aria-label="Filter by rating">
          {[
            { id: "all", label: t("feed.allRatings") },
            { id: "5", label: "5 ★" },
            { id: "4", label: "4 ★" },
          ].map((c) => (
            <button
              key={c.id}
              className="chip"
              aria-pressed={rating === c.id}
              onClick={() => setRating(c.id)}
            >
              {c.label}
            </button>
          ))}
        </div>
        <select className="sort-select" value={sort} onChange={(e) => setSort(e.target.value)} aria-label="Sort">
          <option value="recent">{t("feed.sortRecent")}</option>
          <option value="oldest">{t("feed.sortOldest")}</option>
          <option value="highest">{t("feed.sortHighest")}</option>
          <option value="lowest">{t("feed.sortLowest")}</option>
        </select>
      </div>

      {filtered.length === 0 ? (
        <div className="feed-empty">
          <p className="caption">{t("feed.empty")}</p>
        </div>
      ) : (
        <>
          <div className="reviews-grid">
            {filtered.slice(0, shown).map((r) => (
              <ReviewCard key={r.id} r={r} />
            ))}
          </div>
          {shown < filtered.length && (
            <div className="load-more-row">
              <button className="btn btn-ghost btn-arrow" onClick={() => setShown((s) => s + 9)}>
                {t("feed.loadMore")} <IconArrow />
              </button>
            </div>
          )}
        </>
      )}
    </section>
  );
}

// ===================== Leave-a-review form =====================
const FORMSPREE_ENDPOINT = "https://formspree.io/f/xlgvbeja";

function LeaveReview() {
  const t = useT();
  const [submitted, setSubmitted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [rating, setRating] = useState(0);
  const [hover, setHover] = useState(0);
  const [name, setName] = useState("");
  const [country, setCountry] = useState("");
  const [email, setEmail] = useState("");
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");
  const [retreat, setRetreat] = useState("");
  const [consent, setConsent] = useState(false);
  const [err, setErr] = useState("");

  const wordCount = body.trim().split(/\s+/).filter(Boolean).length;

  async function handleSubmit(e) {
    e.preventDefault();
    setErr("");
    if (!name.trim()) return setErr(t("form.errName"));
    if (!rating) return setErr(t("form.errRating"));
    if (!title.trim()) return setErr(t("form.errTitle"));
    if (body.trim().length < 30) return setErr(t("form.errBody"));
    if (!email.trim()) return setErr(t("form.errEmail"));
    if (!consent) return setErr(t("form.errConsent"));

    setSubmitting(true);
    try {
      const payload = {
        rating: `${rating} / 5`,
        name: name.trim(),
        country: country.trim().toUpperCase().slice(0, 2),
        email: email.trim(),
        retreat: retreat.trim(),
        title: title.trim(),
        review: body.trim(),
        consent: consent ? "yes" : "no",
        _subject: `New Yogavibe review — ${rating}★ from ${name.trim()}`,
      };
      const res = await fetch(FORMSPREE_ENDPOINT, {
        method: "POST",
        headers: { "Accept": "application/json", "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        const msg = data && data.errors && data.errors[0] && data.errors[0].message
          ? data.errors[0].message
          : t("form.errSend");
        setErr(msg);
        setSubmitting(false);
        return;
      }
      setSubmitted(true);
    } catch (e2) {
      setErr(t("form.errNet"));
    } finally {
      setSubmitting(false);
    }
  }

  if (submitted) {
    return (
      <section className="form-section section" id="leave-review">
        <div className="container">
          <div className="form-success reveal">
            <div className="success-mark"><IconCheck /></div>
            <span className="eyebrow" style={{ color: "rgba(246,239,224,0.6)" }}>{t("form.successEyebrow")}</span>
            <h2 className="h2">{t("form.successH1")} <i>{t("form.successEm")}</i></h2>
            <p className="lead">{t("form.successLead")}</p>
            <div style={{ display: "flex", gap: 12, marginTop: 12, flexWrap: "wrap", justifyContent: "center" }}>
              <a href="#all-reviews" className="btn btn-light btn-arrow">{t("form.backFeed")} <IconArrow /></a>
              <button className="btn btn-ghost" style={{ color: "var(--bg)", borderColor: "rgba(246,239,224,0.3)" }} onClick={() => {
                setSubmitted(false); setRating(0); setName(""); setCountry(""); setEmail(""); setTitle(""); setBody(""); setRetreat(""); setConsent(false);
              }}>{t("form.submitAnother")}</button>
            </div>
          </div>
        </div>
      </section>
    );
  }

  return (
    <section className="form-section section" id="leave-review">
      <div className="container">
        <div className="form-grid">
          <div className="reveal">
            <span className="eyebrow">{t("form.eyebrow")}</span>
            <h2 className="h1" style={{ marginTop: 18 }}>
              {t("form.h2l1")} <i>{t("form.h2em")}</i><br/>{t("form.h2l2")}
            </h2>
            <p className="lead" style={{ marginTop: 18 }}>{t("form.lead")}</p>
            <dl className="form-meta">
              <div className="form-meta-row">
                <dt className="form-meta-key">{t("form.whereKey")}</dt>
                <dd className="form-meta-val">{t("form.whereVal")}</dd>
              </div>
              <div className="form-meta-row">
                <dt className="form-meta-key">{t("form.turnKey")}</dt>
                <dd className="form-meta-val">{t("form.turnVal")}</dd>
              </div>
              <div className="form-meta-row">
                <dt className="form-meta-key">{t("form.dataKey")}</dt>
                <dd className="form-meta-val" dangerouslySetInnerHTML={{ __html: t("form.dataVal") }} />
              </div>
            </dl>
          </div>

          <form className="form-card reveal" onSubmit={handleSubmit} noValidate>
            <div className="field">
              <label>{t("form.ratingLabel")}</label>
              <div className="rating-pick" role="radiogroup" aria-label={t("form.ratingLabel")}>
                {[1, 2, 3, 4, 5].map((n) => (
                  <button
                    key={n}
                    type="button"
                    role="radio"
                    aria-checked={rating === n}
                    data-active={(hover ? n <= hover : n <= rating) || undefined}
                    onMouseEnter={() => setHover(n)}
                    onMouseLeave={() => setHover(0)}
                    onClick={() => setRating(n)}
                    aria-label={`${n}`}
                  >
                    <svg viewBox="0 0 24 24" width="26" height="26" aria-hidden="true">
                      <path
                        d="M12 2.5l2.92 6.36 6.96.71-5.2 4.7 1.49 6.83L12 17.6l-6.17 3.5 1.49-6.83-5.2-4.7 6.96-.71L12 2.5z"
                        fill="currentColor"
                      />
                    </svg>
                  </button>
                ))}
                <span style={{ marginLeft: 12, fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.12em", color: "rgba(246,239,224,0.55)", textTransform: "uppercase" }}>
                  {rating ? `${rating} ${t("form.ofFive")}` : t("form.pickRating")}
                </span>
              </div>
            </div>

            <div className="field-row">
              <div className="field">
                <label htmlFor="rv-name">{t("form.nameLabel")}</label>
                <input id="rv-name" type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t("form.namePh")} required />
              </div>
              <div className="field">
                <label htmlFor="rv-country">{t("form.countryLabel")}</label>
                <input id="rv-country" type="text" value={country} onChange={(e) => setCountry(e.target.value)} placeholder={t("form.countryPh")} maxLength="2" />
              </div>
            </div>

            <div className="field-row">
              <div className="field">
                <label htmlFor="rv-email">{t("form.emailLabel")} <span style={{ opacity: 0.6, textTransform: "none", letterSpacing: 0 }}>{t("form.emailPrivate")}</span></label>
                <input id="rv-email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t("form.emailPh")} />
              </div>
              <div className="field">
                <label htmlFor="rv-retreat">{t("form.retreatLabel")}</label>
                <input id="rv-retreat" type="text" value={retreat} onChange={(e) => setRetreat(e.target.value)} placeholder={t("form.retreatPh")} />
              </div>
            </div>

            <div className="field">
              <label htmlFor="rv-title">{t("form.headlineLabel")}</label>
              <input id="rv-title" type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder={t("form.headlinePh")} maxLength="80" required />
            </div>

            <div className="field">
              <label htmlFor="rv-body">{t("form.bodyLabel")}</label>
              <textarea id="rv-body" value={body} onChange={(e) => setBody(e.target.value)} placeholder={t("form.bodyPh")} rows="6" required />
            </div>

            <label className="consent-row">
              <input type="checkbox" checked={consent} onChange={(e) => setConsent(e.target.checked)} />
              <span dangerouslySetInnerHTML={{ __html: t("form.consent") }} />
            </label>

            {err && (
              <div style={{ marginTop: 14, color: "#F2C3A4", fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase" }}>
                {err}
              </div>
            )}

            <div className="form-actions">
              <span className="form-progress">
                {wordCount} {wordCount === 1 ? t("form.wordOne") : t("form.wordMany")} · {body.length}/2000
              </span>
              <button type="submit" className="btn btn-light btn-arrow" disabled={submitting}>
                {submitting ? t("form.sending") : t("form.submit")} {!submitting && <IconSend />}
              </button>
            </div>
          </form>
        </div>
      </div>
    </section>
  );
}

// ===================== FAQ =====================
function FAQ() {
  const t = useT();
  const items = t("faq.items") || [];
  const [open, setOpen] = useState(0);
  return (
    <section className="section container" id="faq">
      <div className="reveal faq-grid">
        <div>
          <span className="eyebrow">{t("faq.eyebrow")}</span>
          <h2 className="h1" style={{ marginTop: 18 }}>
            {t("faq.h2l1")} <i>{t("faq.h2em")}</i>
          </h2>
          <p className="lead" style={{ marginTop: 18 }} dangerouslySetInnerHTML={{ __html: t("faq.lead") }} />
        </div>
        <div className="faq-list">
          {items.map((item, i) => (
            <div key={i} className="faq-item" data-open={open === i || undefined}>
              <button className="faq-q" aria-expanded={open === i} onClick={() => setOpen(open === i ? -1 : i)}>
                <span>{item.q}</span>
                <span className="faq-toggle" aria-hidden="true">{open === i ? "–" : "+"}</span>
              </button>
              <div className="faq-a">
                <div className="faq-a-inner" dangerouslySetInnerHTML={{ __html: item.a }} />
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ===================== Footer =====================
function Footer() {
  const t = useT();
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div className="footer-brand">
            <div className="footer-brand-row">
              <span className="brand-logo brand-logo-lg" role="img" aria-hidden="true"></span>
              <span className="brand-wordmark brand-wordmark-lg">Yogavibe</span>
            </div>
            <p className="footer-tag">{t("footer.tag")}</p>
          </div>
          <div>
            <h4>{t("footer.reviewsHead")}</h4>
            <ul>
              <li><a href="#all-reviews">{t("footer.allReviews")}</a></li>
              <li><a href="#leave-review">{t("footer.leave")}</a></li>
              <li><a href="#faq">{t("footer.faq")}</a></li>
              <li><a href="https://www.trustpilot.com/review/yogavibe.eu" target="_blank" rel="noopener">{t("footer.verify")}</a></li>
            </ul>
          </div>
          <div>
            <h4>{t("footer.retreatsHead")}</h4>
            <ul>
              <li><a href="https://yogavibe.eu/retreats" target="_blank" rel="noopener">{t("footer.upcoming")}</a></li>
              <li><a href="https://yogavibe.eu/custom-retreats" target="_blank" rel="noopener">{t("footer.custom")}</a></li>
              <li><a href="https://yogavibe.eu" target="_blank" rel="noopener">{t("footer.site")}</a></li>
            </ul>
          </div>
          <div>
            <h4>{t("footer.contactHead")}</h4>
            <ul>
              <li>{t("footer.city")}</li>
              <li><a href="mailto:hello@yogavibe.eu">hello@yogavibe.eu</a></li>
              <li><a href="https://instagram.com/yogavibe.eu" target="_blank" rel="noopener">{t("footer.instagram")}</a></li>
            </ul>
          </div>
        </div>
        <div className="footer-bottom">
          <span>© {new Date().getFullYear()} Yogavibe — {t("footer.rights")}</span>
          <span>yogavibe-reviews.com</span>
        </div>
      </div>
    </footer>
  );
}

// ===================== App root =====================
function App() {
  const [locale, setLocaleState] = useState(() => window.YV_I18N.initialLocale());

  // Manual switch: update state, <html lang>, and the URL (?lang=en; nl is default/clean).
  const setLocale = useCallback((l, writeUrl = true) => {
    setLocaleState(l);
    if (writeUrl) {
      try {
        const url = new URL(window.location.href);
        if (l === "nl") url.searchParams.delete("lang");
        else url.searchParams.set("lang", l);
        window.history.replaceState(null, "", url);
      } catch (e) {}
    }
  }, []);

  useEffect(() => { document.documentElement.lang = locale; }, [locale]);

  // IP-based default: only when the visitor hasn't explicitly chosen a language.
  // NL/BE → Dutch (already the default); everyone else → English. Does not touch the URL.
  useEffect(() => {
    if (window.YV_I18N.hasExplicitLang()) return;
    let cancelled = false;
    fetch("/api/geo")
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => {
        if (cancelled || !d) return;
        const c = String(d.country || "").toUpperCase();
        if (c && c !== "NL" && c !== "BE") setLocale("en", false);
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, [setLocale]);

  useReveal();
  const reviews = window.YOGAVIBE_REVIEWS;

  const stats = useMemo(() => {
    const total = reviews.length;
    const sum = reviews.reduce((s, r) => s + r.rating, 0);
    const avg = total ? sum / total : 0;
    const five = reviews.filter((r) => r.rating === 5).length;
    const fiveStarPct = total ? Math.round((five / total) * 100) : 0;
    const lastDate = reviews
      .map((r) => r.date)
      .sort((a, b) => (a < b ? 1 : -1))[0] || new Date().toISOString();
    return { total, avg, fiveStarPct, lastDate };
  }, [reviews]);

  // Update the aggregateRating JSON-LD with live numbers
  useEffect(() => {
    const node = document.getElementById("ld-business");
    if (!node) return;
    try {
      const data = JSON.parse(node.textContent);
      const setAgg = (obj) => {
        if (obj && obj.aggregateRating) {
          obj.aggregateRating.ratingValue = stats.avg.toFixed(2);
          obj.aggregateRating.reviewCount = stats.total;
        }
      };
      if (Array.isArray(data["@graph"])) data["@graph"].forEach(setAgg);
      else setAgg(data);
      node.textContent = JSON.stringify(data);
    } catch (e) {}
  }, [stats]);

  return (
    <LocaleContext.Provider value={{ locale, setLocale }}>
      <Nav />
      <main>
        <Hero stats={stats} />
        <Marquee />
        <Glimpses />
        <ReviewsFeed reviews={reviews} />
        <LeaveReview />
        <FAQ />
      </main>
      <Footer />
    </LocaleContext.Provider>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
