/* hermon-app-v2.jsx — Cluely-style mount. Reuses CountUp/useReveal pattern + existing sections. */

function CountUpV2({ to, dur = 1500, decimals = 0 }) {
  const ref = React.useRef(null);
  const [val, setVal] = React.useState(0);
  React.useEffect(()=>{
    const el = ref.current; if(!el) return;
    const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduce) { setVal(to); return; }
    let raf, started = false;
    const run = ()=>{
      if (started) return; started = true;
      const t0 = performance.now();
      const tick = (now)=>{
        const p = Math.min(1, (now - t0) / dur);
        const e = 1 - Math.pow(1 - p, 3);
        setVal(to * e);
        if (p < 1) raf = requestAnimationFrame(tick); else setVal(to);
      };
      raf = requestAnimationFrame(tick);
    };
    const check = ()=>{
      const vh = window.innerHeight || document.documentElement.clientHeight;
      const r = el.getBoundingClientRect();
      if (r.top < vh * 0.92 && r.bottom > 0) run();
    };
    let io;
    try {
      io = new IntersectionObserver((es)=>{ es.forEach(e=>{ if(e.isIntersecting) run(); }); }, { threshold: 0.4 });
      io.observe(el);
    } catch(e){}
    check();
    window.addEventListener('scroll', check, { passive:true });
    const safety = setTimeout(()=>{ started = true; setVal(to); }, 1600);
    return ()=>{ cancelAnimationFrame(raf); io && io.disconnect(); window.removeEventListener('scroll', check); clearTimeout(safety); };
  }, [to, dur]);
  const txt = val.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
  return <span ref={ref}>{txt}</span>;
}
window.CountUp = CountUpV2;

function useRevealV2(dep) {
  React.useEffect(()=>{
    const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const finish = (el)=>{ el.style.transition='none'; el.style.opacity='1'; el.style.transform='none'; };
    if (reduce) { document.querySelectorAll('.reveal').forEach(finish); return; }
    const timers = new Set();
    const reveal = (el)=>{
      if (el.classList.contains('in')) return;
      el.classList.add('in');
      // safety: guarantee the resting (visible) state even if the transition stalls
      const t = setTimeout(()=> finish(el), 1500);
      timers.add(t);
    };
    const check = ()=>{
      const vh = window.innerHeight || document.documentElement.clientHeight;
      document.querySelectorAll('.reveal:not(.in)').forEach(el=>{
        if (el.getBoundingClientRect().top < vh * 0.92) reveal(el);
      });
    };
    let io;
    try {
      io = new IntersectionObserver((es)=>{ es.forEach(e=>{ if(e.isIntersecting) reveal(e.target); }); },
        { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
      document.querySelectorAll('.reveal').forEach(el=> io.observe(el));
    } catch(e){}
    check();
    window.addEventListener('scroll', check, { passive:true });
    window.addEventListener('resize', check);
    const raf = requestAnimationFrame(check);
    // global safety: nothing stays hidden
    const safety = setTimeout(()=> document.querySelectorAll('.reveal').forEach(finish), 2200);
    return ()=>{ io && io.disconnect(); window.removeEventListener('scroll', check); window.removeEventListener('resize', check); cancelAnimationFrame(raf); clearTimeout(safety); timers.forEach(clearTimeout); };
  }, [dep]);
}

const TWEAK_DEFAULTS_V2 = /*EDITMODE-BEGIN*/{
  "accent": "#6D4AE6",
  "heroVisual": "Dashboard",
  "ctaStyle": "Ink",
  "motion": true,
  "sky": true
}/*EDITMODE-END*/;

function AppV2() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS_V2);
  useRevealV2(t.ctaStyle);

  React.useEffect(()=>{ document.documentElement.style.setProperty('--purple', t.accent); }, [t.accent]);
  React.useEffect(()=>{
    document.body.classList.toggle('no-sky', !t.sky);
  }, [t.sky]);

  return (
    <React.Fragment>
      <NavV2/>
      <main id="top">
        <section className="hero" id="hero">
          <div className="wrap" style={{position:'relative', zIndex:2}}>
            <HeroV2 motion={t.motion} accentCta={t.ctaStyle === "Accent"} visual={t.heroVisual === "Live feed" ? "feed" : t.heroVisual === "Pipeline" ? "pipeline" : "dashboard"}/>
          </div>
        </section>

        <SocialProof/>
        <Problem/>
        <Solution/>
        <Features/>
        <Integrations/>
        {/* <Results/> hidden for now */}
        <ClosingCTA/>
      </main>
      <Footer/>

      <TweaksPanel>
        <TweakSection label="Brand" />
        <TweakColor label="Accent" value={t.accent}
                    options={["#6D4AE6","#7C5CFF","#5B6CFF","#9B4DE0"]}
                    onChange={(v)=> setTweak('accent', v)} />
        <TweakSection label="Hero visual" />
        <TweakSelect label="Show" value={t.heroVisual} options={["Dashboard","Pipeline","Live feed"]}
                    onChange={(v)=> setTweak('heroVisual', v)} />
        <TweakSection label="Primary CTA" />
        <TweakRadio label="Style" value={t.ctaStyle} options={["Ink","Accent"]}
                    onChange={(v)=> setTweak('ctaStyle', v)} />
        <TweakSection label="Motion & backdrop" />
        <TweakToggle label="Live pipeline motion" value={t.motion}
                     onChange={(v)=> setTweak('motion', v)} />
        <TweakToggle label="Lavender sky" value={t.sky}
                     onChange={(v)=> setTweak('sky', v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<AppV2/>);
