/* Home v3  Apple-style: giant headline, body, photo cards */

/* Cycling headline — swaps the whole two-line phrase every few seconds with the
   same mask reveal, Apple-style. Lands on the brand line, then loops.
   Respects reduced-motion (then it just shows the first phrase). */
const HERO_PHRASES = [
  { lead: "Every cert", word: "explained" },
  { lead: "Every cert", word: "compared" },
  { lead: "Every cert", word: "verified" },
  { lead: "We make it", word: "honest" },
];

function CyclingHeadline({ phrases, interval }) {
  const [i, setI] = React.useState(0);
  const last = phrases.length - 1;
  React.useEffect(() => {
    // reduced motion: jump straight to the final line
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setI(last); return; }
    if (i >= last) return; // reached "We make it honest." — stop, no loop
    const id = setTimeout(() => setI(i + 1), interval || 1600);
    return () => clearTimeout(id);
  }, [i, last, interval]);
  const p = phrases[i];
  // key by TEXT so the lead "Every cert" doesn't re-animate while it stays the
  // same; the teal word re-animates on every swap; the final flip re-animates both.
  return (
    <React.Fragment>
      <span className="hp-line">
        <span key={p.lead} className="hp-line-in" style={{ animationDelay: "100ms" }}>{p.lead}</span>
      </span>
      <span className="hp-line">
        <span key={p.word} className="hp-line-in hp-line-accent" style={{ animationDelay: i === 0 ? "260ms" : "0ms" }}>{p.word}</span>
      </span>
    </React.Fragment>
  );
}

/* ── Hero ─────────────────────────────────────────────────────────────────── */
function Hero({ onBrowse, onReadNews }) {
  return (
    <section className="hp-hero">
      <div className="hp-hero-inner">

        <h1 className="hp-h1">
          <CyclingHeadline phrases={HERO_PHRASES} interval={1600} />
        </h1>

        <p className="hp-sub">
          Your whole fitness career, in one place. Compare your first course,
          then plan everything after, from finding work to running your own
          business. We help all the way.
        </p>

      </div>
    </section>
  );
}

/* ── Photo card strip ─────────────────────────────────────────────────────── */
/* The three focuses, the whole journey we help with. The focus sits on the
   bottom of each photo (our own branded shots). */
const CARDS = [
  {
    id: "courses",
    nav: "courses",
    tab: "Compare",
    label: "The honest way to start",
    focus: "See courses",
    sub: "Every approved course side by side. Real prices, real dates, no spin.",
    img: "img/home-courses.jpg",
    alt: "The [tr] course library on a laptop",
  },
  {
    id: "plan",
    nav: "news",
    tab: "Plan",
    label: "Honest help, every step",
    focus: "Plan your career",
    sub: "From your first job to your specialty. The full picture, not a sales pitch.",
    img: "img/home-plan.jpg",
    alt: "A trainer planning over coffee",
  },
  {
    id: "business",
    nav: "courses",
    tab: "Grow",
    label: "Honest as you grow",
    focus: "Run your business",
    sub: "Clients, programs and leads in one place, built on what actually works.",
    img: "img/home-business.jpg",
    alt: "A trainer with the [tr] dashboard",
    wa: "Hey, I am interested to partner up",
  },
];

function PhotoCard({ card, onBrowse, onReadNews, register }) {
  const ref = React.useRef(null);
  const [vis, setVis] = React.useState(false);

  React.useEffect(() => {
    if (!ref.current) return;
    if (register) register(ref.current);
    const io = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setVis(true); io.disconnect(); } },
      { threshold: 0.08 }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);

  const go = () => {
    if (card.wa) {
      window.open("https://wa.me/971541771709?text=" + encodeURIComponent(card.wa), "_blank", "noopener");
      return;
    }
    card.nav === "news" ? onReadNews && onReadNews() : onBrowse && onBrowse();
  };

  return (
    <div
      ref={ref}
      className="hp-pcard"
      style={{
        opacity: vis ? 1 : 0,
        transform: vis ? "none" : "translateY(36px) scale(0.98)",
        transition: "opacity 0.6s cubic-bezier(0.22,1,0.36,1), transform 0.6s cubic-bezier(0.22,1,0.36,1)",
      }}
      onClick={go}
    >
      <div className="hp-pcard-img">
        <img src={card.img} alt={card.alt} loading="lazy" />
      </div>
      <div className="hp-pcard-text">
        <span className="hp-pcard-label">{card.label}</span>
        <span className="hp-pcard-focus">{card.focus}</span>
        <span className="hp-pcard-sub">{card.sub}</span>
      </div>
    </div>
  );
}

function PhotoStrip({ onBrowse, onReadNews }) {
  const [active, setActive] = React.useState(0);
  const cardEls = React.useRef([]);
  const stripRef = React.useRef(null);
  const last = CARDS.length - 1;

  const go = (i) => {
    const n = Math.max(0, Math.min(last, i));
    setActive(n);
    const el = cardEls.current[n];
    if (el && el.scrollIntoView) el.scrollIntoView({ behavior: "smooth", inline: "start", block: "nearest" });
  };

  // Stop the horizontal carousel from trapping vertical scroll: when the wheel
  // intent is mostly vertical, scroll the page instead of the strip sideways.
  React.useEffect(() => {
    const el = stripRef.current;
    if (!el) return;
    const onWheel = (e) => {
      if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
        // normalise line/page wheel deltas to pixels so the page actually moves
        const dy = e.deltaMode === 1 ? e.deltaY * 32
                 : e.deltaMode === 2 ? e.deltaY * window.innerHeight
                 : e.deltaY;
        window.scrollBy(0, dy);
        e.preventDefault();
      }
    };
    el.addEventListener("wheel", onWheel, { passive: false });
    return () => el.removeEventListener("wheel", onWheel);
  }, []);

  return (
    <section className="hp-strip-section">
      <div className="hp-tabs" role="tablist">
        <button className="hp-tabs-arrow" onClick={() => go(active - 1)} disabled={active === 0} aria-label="Previous">&#8249;</button>
        {CARDS.map((c, i) => (
          <button
            key={c.id}
            role="tab"
            aria-selected={i === active}
            className={"hp-tab" + (i === active ? " is-active" : "")}
            onClick={() => go(i)}
          >
            {c.tab}
          </button>
        ))}
        <button className="hp-tabs-arrow" onClick={() => go(active + 1)} disabled={active === last} aria-label="Next">&#8250;</button>
      </div>
      <div className="hp-strip" ref={stripRef}>
        {CARDS.map((c, i) => (
          <PhotoCard
            key={c.id}
            card={c}
            onBrowse={onBrowse}
            onReadNews={onReadNews}
            register={el => (cardEls.current[i] = el)}
          />
        ))}
      </div>
    </section>
  );
}

/* ── Daily Digest showcase ─────────────────────────────────────────────────── */
/* Pulls the latest published stories from the same digest_posts source the Daily
   Digest page reads. Falls back to the approved recent batch if Supabase is
   unreachable, so the home page always shows real, sourced news — never invented. */
const DIGEST_HOME_SB_URL = "https://uyhnfysmsfiagotjfqjs.supabase.co";
const DIGEST_HOME_SB_ANON = "sb_publishable_MlNmf3BIRPXHqjxgyR7VdA_fZXiCMxp";

const DIGEST_HOME_BRIEF =
  "The industry is fighting client dropout, which makes retention the most valuable skill a trainer has. Reformer Pilates keeps gaining value, and two new premium clubs just opened in Dubai.";

const DIGEST_HOME_FALLBACK = [
  { id: "h-d1", time: "yesterday", category: "Retention", image: null,
    title: "Client dropout crisis: what it means for Dubai personal trainers",
    dek: "Most clients quit within months. A platform just rebuilt its product around that fact. Here's why it matters for your income." },
  { id: "h-d2", time: "yesterday", category: "Regulation",
    title: "Dubai establishes a Longevity Authority to regulate the wellness sector",
    dek: "Wellness services now have their own regulator under Law No. 17 of 2026. Worth watching if you train here." },
  { id: "h-d3", time: "yesterday", category: "Youth sport",
    title: "Iniesta launches his academy in Dubai after taking over at Gulf United",
    dek: "Youth sport keeps expanding in the UAE, and growing academies hire coaches." },
  { id: "h-d4", time: "2 days ago", category: "Pilates",
    title: "Peloton signals a move into reformer Pilates with its Skop acquisition",
    dek: "The biggest home-fitness brand wants into reformer. The specialism keeps gaining value." },
  { id: "h-d5", time: "3 days ago", category: "New gym",
    title: "FITCODE opens a flagship premium health club at Q-East, Al Quoz",
    dek: "24,000 sq ft, four studios, a HYROX centre and the brand's first dedicated reformer studio. New floors need new trainers." },
  { id: "h-d6", time: "3 days ago", category: "City",
    title: "Dubai Sports Council launches Active Summer, running to 31 August",
    dek: "A citywide events calendar to keep people training through the heat. Demand for coaches in the slow season." },
];

function useHomeDigest() {
  const [items, setItems] = React.useState(DIGEST_HOME_FALLBACK);
  const [brief, setBrief] = React.useState(DIGEST_HOME_BRIEF);

  React.useEffect(() => {
    const sb = (window.TRAuth && window.TRAuth.client) ||
      (window.supabase && window.supabase.createClient &&
        window.supabase.createClient(DIGEST_HOME_SB_URL, DIGEST_HOME_SB_ANON));
    if (!sb) return; // keep the approved batch
    sb.from("digest_posts").select("*").eq("status", "published")
      .order("published_at", { ascending: false }).limit(20)
      .then((res) => {
        const rows = (res && res.data) || [];
        const briefRow = rows.find((r) => (r.type || "").toLowerCase() === "brief");
        // Home page shows the curated "bait" set (featured=true) - up to 5. Any digest_posts
        // row counts (not just type='news') - our guide-style articles (type PT/pilates/
        // REPs-process/article) are real published content too, just not day-to-day news items.
        const catLabel = { pt: "Careers", "reps-process": "Registration", pilates: "Pilates", article: "Industry News", news: "News", job: "Jobs" };
        const news = rows
          .filter((r) => r.featured)
          .slice(0, 5)
          .map((r) => {
            const all = Array.isArray(r.source_links) ? r.source_links : [];
            const meta = (all.find((l) => l && l.meta) || {}).meta || {};
            const image =
              r.image_url || r.image || r.og_image || r.hero_image ||
              meta.image || meta.image_url ||
              (all.find((l) => l && l.image) || {}).image || null;
            return {
              id: r.slug, time: "", category: meta.category || catLabel[(r.type || "").toLowerCase()] || "Guide",
              title: r.title, dek: r.standfirst || "", image: image,
              url: "/insights/" + r.slug,
            };
          });
        if (news.length) setItems(news);
        if (briefRow && (briefRow.standfirst || briefRow.body))
          setBrief(briefRow.standfirst || briefRow.body);
      })
      .catch((err) => { console.error("[useHomeDigest] fetch failed, showing fallback:", err); });
  }, []);

  return { items, brief };
}

function DigestRow({ item, onReadNews, i }) {
  const ref = React.useRef(null);
  const [vis, setVis] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setVis(true); io.disconnect(); } },
      { threshold: 0.2 }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return (
    <a
      ref={ref}
      className="hp-digest-row"
      href={item.url || "/insights"}
      style={{
        opacity: vis ? 1 : 0,
        transform: vis ? "none" : "translateY(20px)",
        transition: `opacity 0.6s cubic-bezier(0.22,1,0.36,1) ${i * 90}ms, transform 0.6s cubic-bezier(0.22,1,0.36,1) ${i * 90}ms`,
      }}
    >
      <div className="hp-digest-meta">
        <span className="hp-digest-cat">{item.category}</span>
        {item.time ? <span className="hp-digest-time">{item.time}</span> : null}
      </div>
      <div className="hp-digest-body">
        <span className="hp-digest-title">{item.title}</span>
        <span className="hp-digest-dek">{item.dek}</span>
      </div>
      <span className="hp-digest-arrow" aria-hidden="true">&#8594;</span>
    </a>
  );
}

function DailyDigest({ onReadNews, onBrowse }) {
  const { items, brief } = useHomeDigest();
  const headRef = React.useRef(null);
  const [vis, setVis] = React.useState(false);

  React.useEffect(() => {
    if (!headRef.current) return;
    const io = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setVis(true); io.disconnect(); } },
      { threshold: 0.25 }
    );
    io.observe(headRef.current);
    return () => io.disconnect();
  }, []);

  const a = (delay) => ({
    opacity: vis ? 1 : 0,
    transform: vis ? "none" : "translateY(24px)",
    transition: `opacity 0.7s cubic-bezier(0.22,1,0.36,1) ${delay}ms, transform 0.7s cubic-bezier(0.22,1,0.36,1) ${delay}ms`,
  });

  return (
    <section className="hp-digest-section">
      <div className="hp-digest-inner">
        <div ref={headRef} className="hp-digest-head">
          <span className="hp-digest-eyebrow" style={a(0)}>Daily Digest</span>
          <h2 className="hp-digest-h" style={a(80)}>Fresh every day. Sourced, never spun.</h2>
          <p className="hp-digest-brief" style={a(160)}>{brief}</p>
        </div>
        <div className="hp-digest-list">
          {items.map((it, i) => (
            <DigestRow key={it.id} item={it} onReadNews={onReadNews} i={i} />
          ))}
        </div>
        <div className="hp-digest-foot">
          <button className="hp-digest-start" onClick={() => onReadNews && onReadNews()}>
            <span>Read the full Daily Digest</span>
            <span className="hp-digest-start-arrow" aria-hidden="true">&#8594;</span>
          </button>
          <span className="hp-digest-note">New stories every morning. Free to read.</span>
        </div>
      </div>
    </section>
  );
}

/* ── Home ────────────────────────────────────────────────────────────────── */
function Home({ onNavigate, onOpenChat, onOpenCourse, onBrowse, onReadNews, onOpenArticle }) {
  return (
    <main>
      <Hero onBrowse={onBrowse} onReadNews={onReadNews} />
      <PhotoStrip onBrowse={onBrowse} onReadNews={onReadNews} />
      <DailyDigest onReadNews={onReadNews} onBrowse={onBrowse} />
    </main>
  );
}

window.Home = Home;
