/* Site — shell + simple route state across the five pages. */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "ground": "ivory",
  "backToTop": true
}/*EDITMODE-END*/;

function Site() {
  const [route, setRoute] = React.useState('home');
  const onNav = (r) => { setRoute(r); window.scrollTo({ top: 0, behavior: 'auto' }); };

  /* Per-page title + meta description. In a real build these belong in
     server-rendered <head> at one URL per page; the paths below are the
     intended URLs. */
  const meta = {
    home: {
      path: '/',
      title: 'Spring Street Design & Build | Design Build Remodeling in Little Rock, AR',
      description: 'Little Rock design build firm handling interior design, whole-home remodels, kitchen and bath remodeling, and home additions across Central Arkansas — one team from drawings through punch list.',
    },
    about: {
      path: '/about',
      title: 'About Spring Street Design & Build | Little Rock Design Build Firm',
      description: 'Meet Lauren and Ryan Stephens — interior design paired with construction management and real estate insight, serving Little Rock, West Little Rock, North Little Rock, Roland, Maumelle, Conway, Bryant, Sherwood, Cabot.',
    },
    services: {
      path: '/services',
      title: 'Remodeling & Interior Design Services | Little Rock & Central Arkansas',
      description: 'Kitchen and bath remodeling, whole-home remodels, home additions, interior design, and construction management in Little Rock and Central Arkansas. Design, build, or both.',
    },
    approach: {
      path: '/approach',
      title: 'Our Remodeling Process & What It Costs | Spring Street Design & Build',
      description: 'How a Little Rock remodel actually runs: discovery, design, budget, permitting, construction, and completion — plus honest guidance on timelines and investment ranges.',
    },
    portfolio: {
      path: '/portfolio',
      title: 'Remodeling Portfolio | Kitchens, Additions & Whole-Home Remodels in Little Rock',
      description: 'Selected kitchen remodels, home additions, and whole-home renovations in Hillcrest, The Heights, Quapaw Quarter, and across Central Arkansas.',
    },
    contact: {
      path: '/contact',
      title: 'Contact | Spring Street Design & Build, Little Rock AR',
      description: 'Start a remodeling or interior design conversation. Serving Little Rock, West Little Rock, North Little Rock, Roland, Maumelle, Conway, Bryant, Sherwood, Cabot.',
    },
  };

  React.useEffect(() => {
    const m = meta[route] || meta.home;
    document.title = m.title;
    const set = (selector, attrs) => {
      let el = document.head.querySelector(selector);
      if (!el) { el = document.createElement(attrs.tag); document.head.appendChild(el); }
      Object.entries(attrs).forEach(([k, v]) => { if (k !== 'tag') el.setAttribute(k, v); });
    };
    set('meta[name="description"]', { tag: 'meta', name: 'description', content: m.description });
    set('meta[property="og:title"]', { tag: 'meta', property: 'og:title', content: m.title });
    set('meta[property="og:description"]', { tag: 'meta', property: 'og:description', content: m.description });
    set('meta[property="og:type"]', { tag: 'meta', property: 'og:type', content: 'website' });
    set('link[rel="canonical"]', { tag: 'link', rel: 'canonical', href: 'https://springstreetbuild.com' + m.path });
  }, [route]);

  /* Site-wide scroll reveal: every section's content block fades and lifts in
     the first time it enters view. Applied imperatively so each page stays
     plain markup. Safe by construction — anything not observed is shown. */
  const mainRef = React.useRef(null);
  React.useEffect(() => {
    const reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) return;
    const root = mainRef.current;
    if (!root) return;

    let io, cleanupFns = [];
    const show = (el) => {
      el.style.opacity = '1';
      el.style.transform = 'none';
    };

    let raf = 0, raf2 = 0, kick = 0;
    const run = () => {
      const targets = [];
      root.querySelectorAll('section').forEach((sec) => {
        /* Headers and the inquiry/contact band stay static on every page. */
        if (sec.hasAttribute('data-page-header') || sec.hasAttribute('data-static') || sec.closest('[data-static]')) return;
        Array.from(sec.children).forEach((child) => {
          const cs = getComputedStyle(child);
          if (cs.position === 'absolute' || cs.position === 'fixed') return;
          if (child.hasAttribute('aria-hidden')) return;
          if (!child.textContent.trim() && !child.querySelector('img')) return;
          targets.push(child);
        });
      });

      /* Visible if it has entered view OR has already been scrolled past —
         nothing may stay hidden behind a fast scroll. */
      const onScreen = (el) => {
        const r = el.getBoundingClientRect();
        if (r.height === 0) return false; // not measurable yet — do not treat as passed
        return r.bottom <= 0 || r.top < (window.innerHeight || 0) * 0.92;
      };

      targets.forEach((el, i) => {
        if (onScreen(el)) return; // already visible: leave untouched
        el.style.opacity = '0';
        el.style.transform = 'translateY(22px)';
        el.style.transition = 'opacity 720ms var(--ease-quiet) ' + Math.min(i % 4, 3) * 70 + 'ms, transform 720ms var(--ease-quiet) ' + Math.min(i % 4, 3) * 70 + 'ms';
        el.style.willChange = 'opacity, transform';
      });

      const hidden = targets.filter((el) => el.style.opacity === '0');
      if (!hidden.length) return;

      if (typeof IntersectionObserver !== 'undefined') {
        io = new IntersectionObserver((entries) => {
          entries.forEach((e) => { if (e.isIntersecting) { show(e.target); io.unobserve(e.target); } });
        }, { rootMargin: '0px 0px -6% 0px', threshold: 0 });
        hidden.forEach((el) => io.observe(el));
      }

      const onScroll = () => hidden.forEach((el) => { if (onScreen(el)) show(el); });
      window.addEventListener('scroll', onScroll, { passive: true });
      window.addEventListener('resize', onScroll);

      /* Safety net: if anything is still hidden after a few seconds, reveal it. */
      const safety = setInterval(() => {
        onScroll();
        if (!hidden.some((el) => el.style.opacity === '0')) clearInterval(safety);
      }, 600);
      const finalSafety = setTimeout(() => { hidden.forEach(show); clearInterval(safety); }, 6000);

      cleanupFns.push(() => {
        window.removeEventListener('scroll', onScroll);
        window.removeEventListener('resize', onScroll);
        clearInterval(safety);
        clearTimeout(finalSafety);
      });
    };
    /* Wait for layout to settle (double rAF + fonts) so rects are real. */
    raf = requestAnimationFrame(() => { raf2 = requestAnimationFrame(run); });
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(() => { if (!cleanupFns.length) { kick = setTimeout(run, 0); } });

    return () => {
      cancelAnimationFrame(raf2); clearTimeout(kick);
      cancelAnimationFrame(raf);
      if (io) io.disconnect();
      cleanupFns.forEach((fn) => fn());
    };
  }, [route]);

  /* Back to top: appears once the header photo has scrolled away. */
  const [showTop, setShowTop] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setShowTop(window.pageYOffset > 600);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const dark = t.ground === 'oxblood';
  React.useEffect(() => {
    document.documentElement.style.background = dark ? '#4A2426' : '#F2F3EC';
    document.body.style.background = dark ? '#4A2426' : '#F2F3EC';
  }, [dark]);

  const groundVars = dark ? {
    '--site-ground': 'var(--oxblood)',
    '--parchment': 'var(--oxblood-deep, #3A1B1D)',
    '--text-primary': 'var(--ivory)',
    '--text-secondary': 'var(--cream-88)',
    '--text-muted': 'var(--cream-70)',
    '--border-strong': 'var(--cream-22)',
    '--line-soft': 'var(--cream-22)',
    background: 'var(--oxblood)',
    color: 'var(--ivory)',
  } : { background: 'var(--site-ground)' };

  const Page = {
    home: window.HomePage,
    about: window.AboutPage,
    services: window.ServicesPage,
    approach: window.ApproachPage,
    portfolio: window.PortfolioPage,
    contact: window.ContactPage,
  }[route];

  return (
    <div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', position: 'relative', ...groundVars }}>
      <window.Header route={route} onNav={onNav} darkGround={dark} />
      <main ref={mainRef} style={{ flex: 1 }}>
        <Page onNav={onNav} />
      </main>
      <window.Footer onNav={onNav} />

      <button type="button" aria-label="Back to top" title="Back to top"
        onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
        style={{
          position: 'fixed', bottom: '28px', right: '28px', zIndex: 40,
          width: '46px', height: '46px', borderRadius: '50%', cursor: 'pointer',
          background: 'var(--oxblood)', border: '1px solid var(--oxblood)',
          color: 'var(--ivory)', fontSize: '15px', lineHeight: 1,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          opacity: showTop && t.backToTop ? 1 : 0,
          transform: showTop && t.backToTop ? 'none' : 'translateY(10px)',
          pointerEvents: showTop && t.backToTop ? 'auto' : 'none',
          borderColor: dark ? 'var(--cream-70)' : 'var(--oxblood)',
          transition: 'opacity var(--dur-base) var(--ease-quiet), transform var(--dur-base) var(--ease-quiet)',
        }}>
        {'\u2191'}
      </button>

      <TweaksPanel>
        <TweakSection label="Ground" />
        <TweakRadio label="Page color" value={t.ground} options={['ivory', 'oxblood']}
                    onChange={(v) => setTweak('ground', v)} />
        <TweakToggle label="Back-to-top button" value={t.backToTop}
                     onChange={(v) => setTweak('backToTop', v)} />
      </TweaksPanel>
    </div>
  );
}
window.Site = Site;
