// Building blocks for the landing page

// --- Reveal hook: applies .in when element enters viewport
function useReveal() {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            e.target.classList.add("in");
            io.unobserve(e.target);
          }
        });
      },
      { threshold: 0.12, rootMargin: "-40px 0px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return ref;
}

function Reveal({ children, as: Tag = "div", className = "", stagger = false, ...rest }) {
  const ref = useReveal();
  const cls = `${stagger ? "reveal-stagger" : "reveal"} ${className}`.trim();
  return <Tag ref={ref} className={cls} {...rest}>{children}</Tag>;
}

// --- Animated counter
function CountUp({ to, decimals = 0, prefix = "", suffix = "" }) {
  const [val, setVal] = React.useState(0);
  const ref = React.useRef(null);
  const started = React.useRef(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started.current) {
          started.current = true;
          const start = performance.now();
          const dur = 1600;
          const tick = (t) => {
            const p = Math.min(1, (t - start) / dur);
            const eased = 1 - Math.pow(1 - p, 3);
            setVal(to * eased);
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.4 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [to]);
  const formatted = decimals
    ? val.toFixed(decimals)
    : Math.round(val).toLocaleString();
  return <span ref={ref} className="count-up">{prefix}{formatted}{suffix}</span>;
}

// --- Nav
function Nav({ data, onBook }) {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 30);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <nav className={`nav ${scrolled ? "scrolled" : ""}`}>
      <div className="container nav-inner">
        <a href="#top" className="brand-mark" data-comment-anchor="brand">
          <span className="glyph">H</span>
          <span>{data.brand}</span>
        </a>
        <div className="nav-links">
          <a href="#services">Services</a>
          <a href="#process">Process</a>
          <a href="#reviews">Reviews</a>
          <a href="#book">Book</a>
          <a href="#faq">FAQ</a>
        </div>
        <button className="nav-cta" onClick={onBook}>
          <span className="dot"></span>
          Book a tech
        </button>
      </div>
    </nav>
  );
}

// --- Hero
function Hero({ data }) {
  // split title into words for line animation
  const words1 = data.heroTitle.split(" ");
  const words2 = data.heroTitleItalic.split(" ");
  return (
    <section className="hero" id="top">
      <div className="container">
        <div className="hero-grid">
          <div>
            <div className="hero-eyebrow-row">
              <span className="eyebrow">{data.eyebrow}</span>
              <span className="sep"></span>
              <span className="eyebrow">{data.tagline}</span>
            </div>
            <div className="hero-badge">
              <span className="live-dot"></span>
              <span>{data.heroBadge}</span>
            </div>
            <h1>
              <span className="line"><span className="word">{data.heroTitle}</span></span>
              <span className="line"><span className="word italic" style={{fontStyle:"italic"}}>{data.heroTitleItalic}</span></span>
            </h1>
            <p className="hero-body">{data.heroBody}</p>
            <div className="hero-actions">
              <a href="#book" className="btn-primary">
                {data.primaryCta}
                <svg className="arrow" width="16" height="16" viewBox="0 0 16 16" fill="none">
                  <path d="M3 8H13M13 8L8.5 3.5M13 8L8.5 12.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
                </svg>
              </a>
              <a href="tel:5550149920" className="btn-ghost">
                <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                  <path d="M3 3.5C3 3 3.5 2.5 4 2.5H5.5C6 2.5 6.4 2.8 6.5 3.2L7 5C7.1 5.4 7 5.8 6.7 6L5.7 7C6.5 8.5 7.5 9.5 9 10.3L10 9.3C10.2 9 10.6 8.9 11 9L12.8 9.5C13.2 9.6 13.5 10 13.5 10.5V12C13.5 12.5 13 13 12.5 13C7.3 13 3 8.7 3 3.5Z" stroke="currentColor" strokeWidth="1.2"/>
                </svg>
                {data.secondaryCta}
              </a>
            </div>
          </div>

          <div className="hero-visual">
            <div className="crop-tag">F-001 · Field photo</div>
            <div className="photo-slot">
              <span>Replace with hero photo<br/>— master tech on a job site, 4:5 portrait</span>
            </div>
            <div className="ticker">
              <div>
                <div style={{opacity:0.6, fontSize:11, letterSpacing:"0.1em", textTransform:"uppercase", fontFamily:"var(--mono)"}}>Live job</div>
                <div style={{marginTop:4}}>Repipe · Maplewood Dr.</div>
              </div>
              <div className="price">in progress</div>
            </div>
          </div>
        </div>

        <Reveal className="hero-meta-stats" stagger>
          <div className="stat">
            <span className="n">{data.stat1.n}</span>
            <span className="label">{data.stat1.label}</span>
          </div>
          <div className="stat">
            <span className="n">{data.stat2.n}</span>
            <span className="label">{data.stat2.label}</span>
          </div>
          <div className="stat">
            <span className="n">{data.stat3.n}</span>
            <span className="label">{data.stat3.label}</span>
          </div>
          <div className="stat">
            <span className="n">{data.stat4.n}</span>
            <span className="label">{data.stat4.label}</span>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// --- Trust marquee
function Trust() {
  const items = [
    "★ 4.96 Google · 1,820 reviews",
    "BBB A+ Accredited",
    "Licensed · Bonded · Insured $2M",
    "★ Top Rated on Angi · 9 years",
    "★ HomeAdvisor Elite",
    "EPA Lead-Safe Certified",
    "Veteran-owned · Family-operated",
    "NATE certified technicians",
  ];
  const row = [...items, ...items];
  return (
    <div className="trust">
      <div className="trust-row">
        {row.map((s, i) => (
          <div key={i} className="trust-item">
            <span className="star">◆</span>
            <span>{s}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// --- Services
function Services({ data }) {
  return (
    <section className="section" id="services">
      <div className="container">
        <Reveal className="section-head">
          <span className="eyebrow">— What we do</span>
          <h2>A short list of trades,<br/><em>done thoroughly.</em></h2>
        </Reveal>
        <Reveal className="services-grid" stagger>
          {data.services.map((s, i) => (
            <div key={i} className="service-card">
              <span className="num">{String(i+1).padStart(2,"0")} / {String(data.services.length).padStart(2,"0")}</span>
              <h3 className="t">{s.t}</h3>
              <p className="d">{s.d}</p>
              <div className="foot">
                <span>{s.price}</span>
                <span className="arrow">
                  <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
                    <path d="M2 5h6M5 2l3 3-3 3" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
                  </svg>
                </span>
              </div>
            </div>
          ))}
        </Reveal>
      </div>
    </section>
  );
}

// --- Process
function Process() {
  const steps = [
    { t: "Book in 60 seconds", d: "Pick a service, pick a window. You'll see a live ETA and the name of the tech who'll show up." },
    { t: "We arrive on time", d: "Two-hour window, on-time guarantee. If we miss it, the dispatch fee is on us." },
    { t: "Diagnose & price upfront", d: "Flat-rate quote before any work starts. You approve, in writing, on a tablet." },
    { t: "Fix it right, leave it clean", d: "Workmanship guarantee, photos of the finished work, and a job site cleaner than we found it." },
  ];
  return (
    <div className="process-wrap" id="process">
      <Reveal className="process">
        <h2>Four steps between you and a fixed home.</h2>
        <div className="process-steps reveal-stagger" ref={useReveal()}>
          {steps.map((s, i) => (
            <div key={i} className="process-step">
              <div className="num">0{i+1}</div>
              <h3 className="t">{s.t}</h3>
              <p className="d">{s.d}</p>
            </div>
          ))}
        </div>
      </Reveal>
    </div>
  );
}

// --- Promise
function Promise({ data }) {
  return (
    <section className="section">
      <div className="container">
        <Reveal className="section-head">
          <span className="eyebrow">— Why homeowners stay</span>
          <h2>Four promises<br/>we'll never quietly drop.</h2>
        </Reveal>
        <Reveal className="promise-grid" stagger>
          {data.promise.map((p, i) => (
            <div key={i} className="promise-card">
              <div className="check">
                <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                  <path d="M3 7.5L5.5 10L11 4.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
              </div>
              <div>
                <h3 className="t">{p.t}</h3>
                <p className="d">{p.d}</p>
              </div>
            </div>
          ))}
        </Reveal>
      </div>
    </section>
  );
}

window.Reveal = Reveal;
window.CountUp = CountUp;
window.Nav = Nav;
window.Hero = Hero;
window.Trust = Trust;
window.Services = Services;
window.Process = Process;
window.Promise = Promise;
window.useReveal = useReveal;
