/* global React, Icon, Photo, VideoTile, useReveal, useI18n, IMG, HERO_IMAGES */
// Dentertain — Home (Dennis Jakic). White/black/blush. Julian-Bächer voice.

/* [Dentertain-Server-Patch] Pflegbare Website-Bilder (Backend „Website-Bilder").
   siteImages[key] (eigener Upload, /media/…) überschreibt das Demo-Bild; ist nichts
   gepflegt, bleiben die Demo-Bilder erhalten. Getrackter Patch — Baseline:
   deploy/patches/home.jsx.design-original; nach Design-Re-Import erneut anwenden. */
let _siteImages = {};
let _siteExtra = { googleReviews: [], googleReviewUrl: "" };
const _siteImgSubs = new Set();
const _siteExtraSubs = new Set();
// Einmaliger site-content-Load — von BEIDEN Hooks getriggert (Gotcha: hing das
// Fetch nur in useSiteImages, blieb /#/bewerten bei Direktaufruf ohne Daten).
function ensureSiteLoaded() {
  if (window.__DT_SITE_LOADED__) return;
  window.__DT_SITE_LOADED__ = true;
  fetch("/api/site-content", { credentials: "same-origin" })
    .then((r) => (r.ok ? r.json() : null))
    .then((d) => {
      if (!d) return;
      if (d.siteImages) { _siteImages = d.siteImages; _siteImgSubs.forEach((f) => f(_siteImages)); }
      _siteExtra = { googleReviews: Array.isArray(d.googleReviews) ? d.googleReviews : [], googleReviewUrl: d.googleReviewUrl || "" };
      _siteExtraSubs.forEach((f) => f(_siteExtra));
    })
    .catch(() => {});
}
function useSiteImages() {
  const [v, setV] = React.useState(_siteImages);
  React.useEffect(() => {
    _siteImgSubs.add(setV);
    ensureSiteLoaded();
    return () => { _siteImgSubs.delete(setV); };
  }, []);
  return v;
}
// Echte Google-Bewertungen + Bewertungslink (Backend „Google-Bewertungen")
function useSiteExtra() {
  const [v, setV] = React.useState(_siteExtra);
  React.useEffect(() => {
    _siteExtraSubs.add(setV);
    ensureSiteLoaded();
    return () => { _siteExtraSubs.delete(setV); };
  }, []);
  return v;
}
// override (/media|http) direkt, sonst das Demo-Bild (Unsplash-ID oder volle URL).
const siteImg = (imgs, key, fallback, w) => {
  const v = imgs && imgs[key];
  if (typeof v === "string" && v) return v;
  return (typeof fallback === "string" && (fallback.charAt(0) === "/" || /^https?:/.test(fallback))) ? fallback : IMG.base(fallback, w);
};

const HomeHero = ({ onNavigate }) => {
  const { t } = useI18n();
  const site = useSiteImages();
  const HV = window.HERO_VIDEO || {};
  return (
    <section className="hero">
      <div className="hero__inner">
        <div className="hero__copy">
          <span className="hero__eyebrow">
            <span className="sep"></span>
            <span>{t("hero.eyebrow")}</span>
          </span>
          <h1 className="hero__title">
            <span className="line">{t("hero.line1")} {t("hero.line2")}</span>
            <span className="line"><em>{t("hero.line3")}</em></span>
          </h1>
          <p className="hero__sub">{t("hero.sub")}</p>
          <div className="hero__cta-row">
            <button className="btn btn--dark" onClick={() => onNavigate("contact")}>
              {t("hero.cta1")} <Icon name="arrow-right" size={14} />
            </button>
            <button className="btn btn--ghost" onClick={() => onNavigate("portfolio")}>
              {t("hero.cta2")} →
            </button>
          </div>
          <div className="hero__meta">
            <div className="hero__meta-item">
              <span className="dot live"></span>
              <span>{t("hero.meta1")}</span>
            </div>
            <div className="hero__meta-item">
              <span>{t("hero.meta2")}</span>
            </div>
          </div>
        </div>
        <div className="hero__cluster">
          <VideoTile className="photo--pill" src={siteImg(site, "heroVideo1", HV.src)} poster={siteImg(site, "heroPoster1", HV.poster)} />
          <VideoTile className="photo--pill" startAt={6} src={siteImg(site, "heroVideo2", HV.src)} poster={siteImg(site, "heroPoster2", HV.poster)} />
        </div>
      </div>
      <div className="hero__scroll">
        <span>Scroll</span>
        <span className="hero__scroll-line"></span>
      </div>
    </section>);

};

// Three-word kicker (authentic · emotional · unique)
const KickerRow = () => {
  const { t } = useI18n();
  const words = t("hero.kicker");
  return (
    <div className="container">
      <div className="kicker-row">
        {words.map((w, i) =>
        <React.Fragment key={w}>
            <span>{w}</span>
            {i < words.length - 1 ? <span className="dash"></span> : null}
          </React.Fragment>
        )}
      </div>
    </div>);

};

// Marquee on black
const Marquee = () => {
  const { t } = useI18n();
  const items = t("marquee.words");
  const loop = [...items, ...items, ...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee__track">
        {loop.map((w, i) =>
        <span className="marquee__item" key={i}>
            {w} <span className="marquee__star">✦</span>
          </span>
        )}
      </div>
    </div>);

};

// Promise band — emotional list, Julian-Bächer voice
const PromiseBand = () => {
  const { t, lang } = useI18n();
  return (
    <section className="promise">
      <div className="promise__inner reveal">
        <h2 className="promise__list">
          {lang === "en" ? (
            <>
              I capture your <strong>{t("promise.line1")}</strong><br />
              Your <em>{t("promise.line2")}</em> Your <strong>{t("promise.line3")}</strong><br />
              Your <strong>{t("promise.line4")}</strong> {t("promise.connect")} <em>{t("promise.tagline")}</em>
            </>
          ) : (
            <>
              Ich fange euer <strong>{t("promise.line1")}</strong> ein,<br />
              eure <em>{t("promise.line2")}</em>, eure <strong>{t("promise.line3")}</strong>,<br />
              euer <strong>{t("promise.line4")}</strong> {t("promise.connect")} <em>{t("promise.tagline")}</em>
            </>
          )}
        </h2>
        <p className="promise__sub">{t("promise.sub")}</p>
        <span className="promise__sig">{t("promise.sig")}</span>
      </div>
    </section>);

};

const SERVICES = {
  de: [
  { icon: "film", num: "01 / Film", title: "Hochzeitsvideografie", body: "Mein Hauptmedium. Cinematischer Schnitt, echtes Audio, langsame Bewegungen — auf Wunsch mit Drohnen-Aufnahmen und VFX-Akzenten. Euer Film soll sich wie ein Kinofilm anfühlen.", bullets: ["4K · Cinematic Edit", "Original-Ton & Reden", "Optional VFX & Drohne"] },
  { icon: "camera", num: "02 / Foto", title: "Hochzeitsfotografie", body: "Reportage-Stil mit emotionalem Auge. Dynamisch, ohne Inszenierung. 500 – 800 farbkorrigierte Bilder in voller Auflösung, geliefert voraussichtlich nach rund sechs Wochen.", bullets: ["Getting Ready bis Tanzfläche", "Paar- & Familienporträts", "Online-Galerie + Print-Datei"] },
  { icon: "sparkles", num: "03 / Kombi", title: "Foto + Video Komplett", body: "Mein meistgebuchtes Paket. Ein Team, eine Bildsprache, ein Ansprechpartner. Foto und Film aus einer Hand — und alles greift ineinander.", bullets: ["Ein eingespieltes Team", "Konsistenter Look in Foto & Film", "Voller Tag, ein Preis"] },
  { icon: "heart", num: "04 / Standesamt", title: "Standesamt-only", body: "Für die intime Trauung — ohne Feier oder vor der großen Party. Zwei bis vier Stunden, eine Person, ein Fokus.", bullets: ["2 – 4 Stunden", "Trauung + Sektempfang", "Kompakt-Lieferung in ca. 3 Wochen"] },
  { icon: "users", num: "05 / After", title: "After-Wedding-Shoot", body: "Das ungehetzte Shooting nach der Hochzeit. Im Brautkleid am Strand, im Anzug im Wald — die Bilder, für die am Tag keine Zeit war.", bullets: ["Halbtag oder Tag", "Free Choice of Location", "Reise-Pakete weltweit"] },
  { icon: "play", num: "06 / Doku", title: "Dokumentationsfilm", body: "Wenn der ganze Tag wirken soll, nicht nur die Highlights. Ein 20 – 40 Minuten Doku-Schnitt mit längeren Szenen, vollen Reden und mehr Raum zum Atmen.", bullets: ["20 – 40 Minuten Schnitt", "Vollständige Reden", "Optional in Cinema-DCP"] }],

  en: [
  { icon: "film", num: "01 / Film", title: "Wedding videography", body: "My main craft. Cinematic edit, real audio, slow motion — optionally with drone footage and VFX accents. Your film should feel like a film.", bullets: ["4K · cinematic edit", "Original audio & speeches", "Optional VFX & drone"] },
  { icon: "camera", num: "02 / Photo", title: "Wedding photography", body: "Reportage style with an emotional eye. Dynamic, never staged. 500 – 800 color-graded images at full resolution, usually delivered after around six weeks.", bullets: ["Getting ready → dance floor", "Couple & family portraits", "Online gallery + print files"] },
  { icon: "sparkles", num: "03 / Combo", title: "Photo + Video full package", body: "My most-booked package. One team, one language, one contact. Photo and film coming together — designed to interlock.", bullets: ["One well-rehearsed team", "Consistent look in photo & film", "Full day, one price"] },
  { icon: "heart", num: "04 / Civil", title: "Civil ceremony only", body: "For the intimate registry — without or before the party. Two to four hours, one person, one focus.", bullets: ["2 – 4 hours", "Ceremony + reception", "Compact delivery in about 3 weeks"] },
  { icon: "users", num: "05 / After-wedding", title: "After-wedding shoot", body: "The unhurried shoot after the wedding. In your dress at the coast, in your suit in a forest — the images there was no time for on the day.", bullets: ["Half day or full day", "Free location choice", "Worldwide travel packages"] },
  { icon: "play", num: "06 / Doc", title: "Documentary film", body: "When the whole day should resonate, not just the highlights. A 20 – 40 minute doc edit with full speeches and room to breathe.", bullets: ["20 – 40 minute edit", "Full speeches", "Optionally on Cinema-DCP"] }]

};

const Services = ({ onNavigate }) => {
  const { lang, t } = useI18n();
  const items = SERVICES[lang] || SERVICES.de;
  return (
    <section>
      <div className="container">
        <div className="section-head reveal">
          <span className="eyebrow">{t("services.eyebrow")}</span>
          <h2 className="h1">{t("services.title.a")} <em>{t("services.title.b")}</em></h2>
          <p className="lead">{t("services.lead")}</p>
        </div>
        <div className="services">
          {items.map((s, i) =>
          <div className={`service-card reveal delay-${i % 3 + 1}`} key={s.title}>
              <div className="service-card__num">{s.num}</div>
              <div className="service-card__icon">
                <Icon name={s.icon} size={36} stroke={1.5} />
              </div>
              <h3 className="service-card__title">{s.title}</h3>
              <p className="service-card__body">{s.body}</p>
              <ul className="service-card__list">
                {s.bullets.map((b) => <li key={b}>{b}</li>)}
              </ul>
              <a className="service-card__link" onClick={() => onNavigate("contact")}>
                {t("services.cta")} <Icon name="arrow-right" size={12} />
              </a>
            </div>
          )}
        </div>
      </div>
    </section>);

};

// About — Dennis intro
const About = ({ onNavigate }) => {
  const { t } = useI18n();
  const site = useSiteImages();
  return (
    <section className="about">
      <div className="about__inner">
        <div className="about__visual reveal">
          {/* Reihenfolge bewusst getauscht (Wunsch 2026-07-22): Slot about2 links, about1 rechts */}
          <Photo src={siteImg(site, "about2", "1469371670807-013ccf25f16a", 900)} className="" />
          <Photo src={siteImg(site, "about1", "1525258946800-98cfd641d0de", 900)} className="" />
          <div className="about__badge">{t("about.badge")}</div>
        </div>
        <div className="about__copy reveal delay-2">
          <span className="eyebrow">{t("about.eyebrow")}</span>
          <p className="about__hi">{t("about.hi")}</p>
          <h2 className="h1">{t("about.title.a")} <em>{t("about.title.b")}</em></h2>
          <p>{t("about.p1")}</p>
          <p>{t("about.p2")}</p>
          <p>{t("about.p3")}</p>
          <p className="about__quote">{t("about.quote")}</p>
          <div className="about__stats">
            <div>
              <div className="about__stat-num">{t("about.stat1.num")}</div>
              <div className="about__stat-label">{t("about.stat1.lbl")}</div>
            </div>
            <div>
              <div className="about__stat-num">{t("about.stat2.num")}</div>
              <div className="about__stat-label">{t("about.stat2.lbl")}</div>
            </div>
          </div>
          <div style={{ marginTop: 16 }}>
            <button className="btn btn--secondary" onClick={() => onNavigate("contact")}>
              {t("about.cta")} <Icon name="arrow-right" size={14} />
            </button>
          </div>
        </div>
      </div>
    </section>);

};

// Style strip — Julian-Bächer's three-card row
const StyleStrip = () => {
  const { t } = useI18n();
  const site = useSiteImages();
  const items = t("style.items");
  const demo = ["1606800052052-a08af7148866", "1519225421980-715cb0215aed", "1525258946800-98cfd641d0de"];
  const imgs = [siteImg(site, "style1", demo[0], 700), siteImg(site, "style2", demo[1], 700), siteImg(site, "style3", demo[2], 700)];

  return (
    <section className="style-strip">
      <div className="container">
        <div className="section-head reveal">
          <span className="eyebrow">{t("style.eyebrow")}</span>
          <h2 className="h1">{t("style.title.a")} <em>{t("style.title.b")}</em></h2>
          <p className="lead">{t("style.lead")}</p>
        </div>
        <div className="style-strip__grid">
          {items.map((it, i) =>
          <div className={`style-strip__card reveal delay-${i + 1}`} key={it.t}>
              <div className="style-strip__media">
                <img src={imgs[i]} alt={it.t} loading="lazy" />
              </div>
              <span className="style-strip__title">{it.t}</span>
              <p className="style-strip__body">{it.b}</p>
            </div>
          )}
        </div>
      </div>
    </section>);

};

const Gear = () => {
  const { t } = useI18n();
  const site = useSiteImages();
  const items = t("gear.items");
  return (
    <section className="gear">
      <div className="container">
        <div className="section-head reveal">
          <span className="eyebrow">{t("gear.eyebrow")}</span>
          <h2 className="h1">{t("gear.title.a")} <em>{t("gear.title.b")}</em></h2>
          <p className="lead">{t("gear.lead")}</p>
        </div>
        <div className="gear-photo reveal">
          <image-slot id="gear-equipment" shape="rounded" radius="14" fit="cover" src={siteImg(site, "gear", "https://images.unsplash.com/photo-1516035069371-29a1b244cc32?w=1400&auto=format&fit=crop&q=80")} placeholder="Foto deines Equipments hierher ziehen"></image-slot>
        </div>
        <div className="gear-grid">
          {items.map((it, i) =>
          <div className={`gear-card reveal delay-${i % 4 + 1}`} key={it.t}>
              <div className="gear-card__num">0{i + 1}</div>
              <div className="gear-card__title">{it.t}</div>
              <div className="gear-card__body">{it.b}</div>
            </div>
          )}
        </div>
      </div>
    </section>);

};

const Process = () => {
  const { t } = useI18n();
  const steps = t("process.steps");
  return (
    <section className="process">
      <div className="process__giant">{t("process.giant")}</div>
      <div className="container process__head reveal">
        <span className="eyebrow">{t("process.eyebrow")}</span>
        <h2 className="h1" style={{ color: "#FFF" }}>
          {t("process.title.a")} <em>{t("process.title.b")}</em>
        </h2>
        <p className="lead">{t("process.lead")}</p>
      </div>
      <div className="container">
        <div className="process__grid">
          {steps.map((p, i) =>
          <div className={`process-step reveal delay-${i + 1}`} key={p.n}>
              <span className="process-step__num">{p.n} ─</span>
              <h3 className="process-step__title">{p.t}</h3>
              <p className="process-step__body">{p.b}</p>
            </div>
          )}
        </div>
      </div>
    </section>);

};

/* Google-Bewertungen: NUR echte, im Backend gespiegelte Rezensionen (keine Fakes).
   Ohne Einträge und ohne Bewertungslink rendert die Sektion gar nicht. */
const REV_MON_DE = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
const REV_MON_EN = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
/* ISO-Datum (aus dem Backend-Datumsfeld) → „Juli 2026"; Alt-Freitext bleibt unverändert */
const fmtReviewDate = (d, lang) => {
  const m = /^(\d{4})-(\d{2})(?:-\d{2})?$/.exec(String(d || ""));
  if (!m) return d || "";
  const mon = parseInt(m[2], 10) - 1;
  if (mon < 0 || mon > 11) return d;
  return (lang === "en" ? REV_MON_EN : REV_MON_DE)[mon] + " " + m[1];
};
const Testimonial = () => {
  const { lang, t } = useI18n();
  const { googleReviews, googleReviewUrl } = useSiteExtra();
  /* Sektion mountet ASYNCHRON (nach /api/site-content) — der Seiten-useReveal hat dann
     schon gescannt und niemand beobachtet das neue .reveal → blieb unsichtbar (opacity 0).
     Eigener useReveal re-scannt nach jedem Render dieser Komponente. */
  useReveal();
  const items = googleReviews || [];
  const [idx, setIdx] = React.useState(0);
  const item = items.length ? items[idx % items.length] : null;
  const next = () => setIdx((i) => (i + 1) % Math.max(1, items.length));
  const prev = () => setIdx((i) => (i - 1 + items.length) % Math.max(1, items.length));
  React.useEffect(() => {
    if (items.length < 2) return;
    const id = setInterval(next, 9000);
    return () => clearInterval(id);
  }, [items.length]);
  if (!items.length && !googleReviewUrl) return null;
  const stars = item ? Math.max(1, Math.min(5, parseInt(item.stars, 10) || 5)) : 5;
  if (!item) {
    return (
      <section className="testimonial">
        <div className="testimonial__inner reveal">
          <span className="eyebrow solo">{t("testi.eyebrow")}</span>
          <p className="testimonial__quote" style={{ marginTop: 24 }}>{lang === "en" ? "Have we filmed your day? Your review helps other couples." : "Waren wir für euch im Einsatz? Eure Bewertung hilft anderen Paaren."}</p>
          <a className="btn btn--dark testimonial__gcta" href={googleReviewUrl} target="_blank" rel="noopener noreferrer">{t("testi.cta")} <Icon name="arrow-up-right" size={14} /></a>
        </div>
      </section>
    );
  }
  return (
    <section className="testimonial">
      <div className="testimonial__inner reveal">
        <div className="testimonial__mark">"</div>
        <div className="testimonial__stars" aria-label={stars + " von 5 Sternen"}>{"★".repeat(stars)}{"☆".repeat(5 - stars)}</div>
        <p className={"testimonial__quote" + ((item.text || "").length > 150 ? " testimonial__quote--long" : "")} key={idx}>{item.text}</p>
        <div className="testimonial__attr">— {item.author}{item.date ? " · " + fmtReviewDate(item.date, lang) : ""} · {t("testi.via")}</div>
        {googleReviewUrl ? (
          <a className="btn btn--ghost testimonial__gcta" href={googleReviewUrl} target="_blank" rel="noopener noreferrer">{t("testi.cta")} <Icon name="arrow-up-right" size={13} /></a>
        ) : null}
        {items.length > 1 ? (
          <div className="testimonial__nav">
            <button onClick={prev} aria-label="Vorherige Bewertung">
              <Icon name="arrow-left" size={16} />
            </button>
            <button onClick={next} aria-label="Nächste Bewertung">
              <Icon name="arrow-right" size={16} />
            </button>
          </div>
        ) : null}
      </div>
    </section>);

};

const LogoStrip = () => {
  const { lang } = useI18n();
  return (
    <section className="tight">
      <div className="container">
        <div className="logo-strip">
          <span className="logo-strip__label">{lang === "en" ? "Featured & recognised by" : "Featured & empfohlen von"}</span>
          <div className="logo-strip__items">
            <span className="logo-strip__item"></span>
            <span className="logo-strip__item"></span>
            <span className="logo-strip__item"></span>
            <span className="logo-strip__item"></span>
          </div>
        </div>
      </div>
    </section>);

};

const CtaBand = ({ onNavigate }) => {
  const { t } = useI18n();
  return (
    <section className="cta-band">
      <div className="cta-band__inner reveal">
        <span className="eyebrow solo">{t("cta.eyebrow")}</span>
        <h2 className="cta-band__title">{t("cta.title.a")} <em>{t("cta.title.b")}</em></h2>
        <p className="cta-band__sub">{t("cta.sub")}</p>
        <div style={{ display: "inline-flex", gap: 14, flexWrap: "wrap", justifyContent: "center" }}>
          <button className="btn btn--dark" onClick={() => onNavigate("contact")}>
            {t("cta.btn1")} <Icon name="arrow-right" size={14} />
          </button>
          <button className="btn btn--outline-light" onClick={() => onNavigate("portfolio")}>
            {t("cta.btn2")}
          </button>
        </div>
      </div>
    </section>);

};

const HomePage = ({ onNavigate }) => {
  useReveal();
  return (
    <>
      <HomeHero onNavigate={onNavigate} />
      <KickerRow />
      <PromiseBand />
      <Marquee />
      <Services onNavigate={onNavigate} />
      <StyleStrip />
      <About onNavigate={onNavigate} />
      <Process />
      <Testimonial />
      <Gear />
      <CtaBand onNavigate={onNavigate} />
    </>);

};

/* Eigene Bewerten-Seite (#/bewerten) — der Link, den Dennis Brautpaaren schickt.
   Gebrandeter Zwischenschritt: Danke-Note + großer Button zum Google-Formular. */
const BewertenPage = ({ onNavigate }) => {
  const { lang } = useI18n();
  const { googleReviewUrl } = useSiteExtra();
  const de = lang !== "en";
  return (
    <div className="page-enter" style={{ paddingTop: 160, paddingBottom: 96, minHeight: "70vh", background: "#FFFFFF" }}>
      <div className="container" style={{ textAlign: "center", maxWidth: 720 }}>
        <span className="eyebrow solo">{de ? "Danke" : "Thank you"}</span>
        <h1 className="h-display" style={{ marginTop: 16 }}>{de ? <>Eure Meinung <em>zählt.</em></> : <>Your words <em>matter.</em></>}</h1>
        <p className="lead" style={{ margin: "28px auto 0" }}>
          {de
            ? "Schön, dass ihr hier seid! Eine ehrliche Google-Bewertung dauert zwei Minuten — und hilft anderen Paaren, den richtigen Menschen für ihren Tag zu finden."
            : "Great to have you here! An honest Google review takes two minutes — and helps other couples find the right person for their day."}
        </p>
        <p className="p" style={{ margin: "18px auto 0", maxWidth: 560, color: "var(--fg-2)" }}>
          {de
            ? "Und wenn ihr mögt: Schreibt gern zwei, drei Sätze dazu — was euch in Erinnerung geblieben ist, ein Moment, der Film, die Fotos. Ein paar persönliche Worte helfen künftigen Paaren mehr als jeder Stern."
            : "And if you like, add two or three sentences — what stayed with you, a moment, the film, the photos. A few personal words help future couples more than any star."}
        </p>
        <div style={{ marginTop: 36 }}>
          {googleReviewUrl ? (
            <a className="btn btn--dark" href={googleReviewUrl} target="_blank" rel="noopener noreferrer" style={{ fontSize: 13, padding: "16px 28px" }}>
              {de ? "Jetzt auf Google bewerten" : "Review on Google now"} <Icon name="arrow-up-right" size={14} />
            </a>
          ) : (
            <button className="btn btn--dark" onClick={() => onNavigate && onNavigate("contact")}>
              {de ? "Zum Kontakt" : "Contact"} <Icon name="arrow-right" size={14} />
            </button>
          )}
        </div>
        <p className="p" style={{ marginTop: 28, color: "var(--fg-3)", fontSize: 13.5 }}>
          {de ? "Der Button öffnet das offizielle Google-Bewertungsformular für DENTERTAIN." : "The button opens the official Google review form for DENTERTAIN."}
        </p>
      </div>
    </div>
  );
};

Object.assign(window, { HomePage, BewertenPage });