// Generic IntersectionObserver-based reveal helper
function useReveal() {
  React.useEffect(() => {
    const els = document.querySelectorAll('.reveal, .reveal-stagger');
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  }, []);
}

// Plate form: 3D tilt that follows cursor — also applied to info panels
function usePlateTilt(enabled) {
  React.useEffect(() => {
    const selector = '.cta-form, .bh-card, .module-card, .tier-art';
    const els = Array.from(document.querySelectorAll(selector));
    if (!els.length) return;
    if (!enabled) {
      els.forEach(el => { el.style.removeProperty('--px'); el.style.removeProperty('--py'); });
      return;
    }
    const cleanups = [];
    els.forEach(el => {
      let raf = 0;
      const onMove = (e) => {
        const r = el.getBoundingClientRect();
        const px = ((e.clientX - r.left) / r.width - 0.5) * 2;
        const py = ((e.clientY - r.top) / r.height - 0.5) * 2;
        cancelAnimationFrame(raf);
        raf = requestAnimationFrame(() => {
          el.style.setProperty('--px', px.toFixed(3));
          el.style.setProperty('--py', py.toFixed(3));
        });
      };
      const onLeave = () => {
        el.style.setProperty('--px', '0');
        el.style.setProperty('--py', '0');
      };
      el.addEventListener('mousemove', onMove);
      el.addEventListener('mouseleave', onLeave);
      cleanups.push(() => {
        el.removeEventListener('mousemove', onMove);
        el.removeEventListener('mouseleave', onLeave);
        cancelAnimationFrame(raf);
      });
    });
    return () => cleanups.forEach(fn => fn());
  }, [enabled]);
}

// Magnetic primary buttons: pull toward cursor when nearby
function useMagneticButtons(enabled) {
  React.useEffect(() => {
    if (!enabled) {
      document.querySelectorAll('.btn-primary').forEach(b => {
        b.style.setProperty('--mag-x', '0px');
        b.style.setProperty('--mag-y', '0px');
      });
      return;
    }
    const btns = document.querySelectorAll('.btn-primary');
    const cleanups = [];
    btns.forEach(btn => {
      let raf = 0;
      const onMove = (e) => {
        const r = btn.getBoundingClientRect();
        const cx = r.left + r.width / 2;
        const cy = r.top + r.height / 2;
        const dx = e.clientX - cx;
        const dy = e.clientY - cy;
        cancelAnimationFrame(raf);
        raf = requestAnimationFrame(() => {
          btn.style.setProperty('--mag-x', `${dx * 0.18}px`);
          btn.style.setProperty('--mag-y', `${dy * 0.22}px`);
        });
      };
      const onLeave = () => {
        cancelAnimationFrame(raf);
        btn.style.setProperty('--mag-x', '0px');
        btn.style.setProperty('--mag-y', '0px');
      };
      btn.addEventListener('mousemove', onMove);
      btn.addEventListener('mouseleave', onLeave);
      cleanups.push(() => {
        btn.removeEventListener('mousemove', onMove);
        btn.removeEventListener('mouseleave', onLeave);
      });
    });
    return () => cleanups.forEach(f => f());
  }, [enabled]);
}

// Cards spotlight: track cursor for radial-gradient highlight
function useCardSpotlight(enabled) {
  React.useEffect(() => {
    if (!enabled) return;
    const cards = document.querySelectorAll('.module-card, .bh-card, .cust-cell');
    const cleanups = [];
    cards.forEach(card => {
      const onMove = (e) => {
        const r = card.getBoundingClientRect();
        const x = ((e.clientX - r.left) / r.width) * 100;
        const y = ((e.clientY - r.top) / r.height) * 100;
        card.style.setProperty('--spot-x', `${x}%`);
        card.style.setProperty('--spot-y', `${y}%`);
      };
      card.addEventListener('mousemove', onMove);
      cleanups.push(() => card.removeEventListener('mousemove', onMove));
    });
    return () => cleanups.forEach(f => f());
  }, [enabled]);
}

// Apply tweak values to the document via CSS variables and class toggles
function useTweakStyles(t) {
  React.useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty('--signal', t.signalColor);
    // derive a lighter signal-deep based on signal
    r.style.setProperty('--ink', t.inkColor);
    r.style.setProperty('--bone', t.boneColor);
    r.style.setProperty('--display', `"${t.displayFont}", "Bebas Neue", "Archivo Black", system-ui, sans-serif`);
    r.style.setProperty('--heading-scale', t.headingScale);
    r.style.setProperty('--body-scale', t.bodyScale);
    r.style.setProperty('--btn-radius', `${t.buttonRadius}px`);
    r.style.setProperty('--shell-max', `${t.containerWidth}px`);
    r.style.setProperty('--grain-opacity', `${t.grainStrength / 100}`);
    r.style.setProperty('--hero-zoom', t.heroZoom);
    r.style.setProperty('--hero-overlay', `${t.heroOverlay / 100}`);

    // density
    const padScale = t.sectionDensity === 'compact' ? 0.7 : t.sectionDensity === 'spacious' ? 1.3 : 1;
    r.style.setProperty('--pad-scale', padScale);

    // toggle classes
    document.body.classList.toggle('no-grain', !t.showGrain);
    document.body.classList.toggle('hide-marquee', !t.showMarquee);
    document.body.classList.toggle('hide-calculator', !t.showCalculator);
    document.body.classList.toggle('hide-customers', !t.showCustomers);
    document.body.classList.toggle('hide-faq', !t.showFAQ);
    document.body.classList.toggle('hide-modules', !t.showModules);
    document.body.classList.toggle('uppercase-everything', t.uppercaseEverything);
    document.body.classList.toggle('reduce-motion', t.reduceMotion);
    r.style.setProperty('--extra-tracking', `${t.letterSpacing / 1000}em`);

    // accent mode preset overrides
    if (t.accentMode === 'rust') {
      r.style.setProperty('--signal', '#c2552a');
    } else if (t.accentMode === 'moss') {
      r.style.setProperty('--signal', '#7a8c4a');
    } else if (t.accentMode === 'sky') {
      r.style.setProperty('--signal', '#6b8aa3');
    } else if (t.accentMode === 'mono') {
      r.style.setProperty('--signal', t.boneColor);
    }
    // 'yellow' / 'custom' fall through to user-picked signalColor (already set above)
  }, [t]);
}

const FONT_OPTIONS = [
  { value: 'Anton', label: 'Anton' },
  { value: 'Archivo Black', label: 'Archivo' },
  { value: 'Bebas Neue', label: 'Bebas' },
  { value: 'Oswald', label: 'Oswald' },
];

function useGoogleFont(family) {
  React.useEffect(() => {
    if (family === 'Oswald' && !document.getElementById('font-oswald')) {
      const l = document.createElement('link');
      l.id = 'font-oswald';
      l.rel = 'stylesheet';
      l.href = 'https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&display=swap';
      document.head.appendChild(l);
    }
  }, [family]);
}

function App() {
  const [t, setT] = useTweaks(window.TWEAK_DEFAULTS);
  useReveal();
  useTweakStyles(t);
  useGoogleFont(t.displayFont);
  usePlateTilt(t.plateTilt && !t.reduceMotion);
  useMagneticButtons(t.magneticButtons && !t.reduceMotion);
  useCardSpotlight(t.cardSpotlight);

  const reset = () => {
    Object.entries(window.TWEAK_DEFAULTS).forEach(([k, v]) => setT(k, v));
  };

  return (
    <>
      <Nav/>
      <Hero/>
      {t.showMarquee && <Marquee/>}
      <Problem/>
      <Tiers/>
      {t.showModules && <Modules/>}
      {t.showCustomers && <Customers/>}
      <BuyHire/>
      {t.showWizard && <Wizard/>}
      {t.showCalculator && <Calculator/>}
      {t.showFAQ && <FAQ/>}
      <CTA/>
      <Footer/>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Color"/>
        <TweakRadio label="Accent preset" value={t.accentMode}
                    options={[
                      {value:'yellow', label:'Sun'},
                      {value:'rust', label:'Rust'},
                      {value:'moss', label:'Moss'},
                      {value:'sky', label:'Sky'},
                      {value:'mono', label:'Mono'},
                    ]}
                    onChange={v => setT('accentMode', v)}/>
        <TweakColor label="Signal" value={t.signalColor} onChange={v => { setT('signalColor', v); setT('accentMode', 'yellow'); }}/>
        <TweakColor label="Ink (bg)" value={t.inkColor} onChange={v => setT('inkColor', v)}/>
        <TweakColor label="Bone (fg)" value={t.boneColor} onChange={v => setT('boneColor', v)}/>

        <TweakSection label="Type"/>
        <TweakSelect label="Display font" value={t.displayFont} options={FONT_OPTIONS}
                     onChange={v => setT('displayFont', v)}/>
        <TweakSlider label="Heading scale" value={t.headingScale} min={0.7} max={1.4} step={0.05}
                     onChange={v => setT('headingScale', v)}/>
        <TweakSlider label="Body scale" value={t.bodyScale} min={0.85} max={1.2} step={0.05}
                     onChange={v => setT('bodyScale', v)}/>
        <TweakSlider label="Letter spacing" value={t.letterSpacing} min={-20} max={60} step={2} unit="‰"
                     onChange={v => setT('letterSpacing', v)}/>
        <TweakToggle label="Uppercase everything" value={t.uppercaseEverything}
                     onChange={v => setT('uppercaseEverything', v)}/>

        <TweakSection label="Layout"/>
        <TweakRadio label="Density" value={t.sectionDensity}
                    options={['compact','normal','spacious']}
                    onChange={v => setT('sectionDensity', v)}/>
        <TweakSlider label="Button radius" value={t.buttonRadius} min={0} max={28} step={1} unit="px"
                     onChange={v => setT('buttonRadius', v)}/>
        <TweakSlider label="Container width" value={t.containerWidth} min={1200} max={1920} step={20} unit="px"
                     onChange={v => setT('containerWidth', v)}/>

        <TweakSection label="Hero & texture"/>
        <TweakSlider label="Hero photo zoom" value={t.heroZoom} min={0.85} max={1.4} step={0.05}
                     onChange={v => setT('heroZoom', v)}/>
        <TweakSlider label="Hero overlay" value={t.heroOverlay} min={0} max={70} step={5} unit="%"
                     onChange={v => setT('heroOverlay', v)}/>
        <TweakToggle label="Film grain" value={t.showGrain}
                     onChange={v => setT('showGrain', v)}/>
        <TweakSlider label="Grain strength" value={t.grainStrength} min={0} max={20} step={1} unit="%"
                     onChange={v => setT('grainStrength', v)}/>

        <TweakSection label="Interactions"/>
        <TweakToggle label="Magnetic buttons" value={t.magneticButtons}
                     onChange={v => setT('magneticButtons', v)}/>
        <TweakToggle label="Card spotlight" value={t.cardSpotlight}
                     onChange={v => setT('cardSpotlight', v)}/>
        <TweakToggle label="Plate form tilt" value={t.plateTilt}
                     onChange={v => setT('plateTilt', v)}/>
        <TweakToggle label="Reduce motion" value={t.reduceMotion}
                     onChange={v => setT('reduceMotion', v)}/>

        <TweakSection label="Sections"/>
        <TweakToggle label="Press marquee" value={t.showMarquee}
                     onChange={v => setT('showMarquee', v)}/>
        <TweakToggle label="Find Your Fit (wizard)" value={t.showWizard}
                     onChange={v => setT('showWizard', v)}/>
        <TweakToggle label="Modules" value={t.showModules}
                     onChange={v => setT('showModules', v)}/>
        <TweakToggle label="Use cases" value={t.showCustomers}
                     onChange={v => setT('showCustomers', v)}/>
        <TweakToggle label="Calculator" value={t.showCalculator}
                     onChange={v => setT('showCalculator', v)}/>
        <TweakToggle label="FAQ" value={t.showFAQ}
                     onChange={v => setT('showFAQ', v)}/>

        <TweakSection label=""/>
        <TweakButton label="Reset all" secondary onClick={reset}/>
      </TweaksPanel>
    </>
  );
}

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