// sections-top.jsx — Hero + Problème + Expertise

const { useState, useEffect, useRef } = React;

const HERO_WORDS = [
  { word: 'go-to-market', hl: '' },
  { word: 'expérience client', hl: ' t-highlight--mint' },
  { word: 'croissance', hl: ' t-highlight--butter' },
];

function RotatingWord({ words, interval = 2800 }) {
  const [state, setState] = useState({ current: 0, prev: null });

  useEffect(() => {
    if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const id = setInterval(() => {
      setState(s => ({ current: (s.current + 1) % words.length, prev: s.current }));
    }, interval);
    return () => clearInterval(id);
  }, [words.length, interval]);

  return (
    <span className="word-rotator">
      <span className="sr-only">{words[0].word}.</span>
      {words.map((w, i) => (
        <span key={w.word} aria-hidden="true"
          className={'word-rotator__word' +
            (i === state.current ? ' is-active' : i === state.prev ? ' is-leaving' : '')}>
          <em className={'t-highlight' + w.hl}>{w.word}</em>.
        </span>
      ))}
    </span>
  );
}

const TRAIL_RATE = 0.3;

function TopoField() {
  const rootRef = useRef(null);
  const svgRef = useRef(null);
  const trailRef = useRef(null);

  useEffect(() => {
    const svg = svgRef.current;
    if (!svg) return;
    const CX = 1152, CY = 342;
    const groups = [[], [], []];
    topoRingPaths({ cx: CX, cy: CY, r0: 70, count: 16, growth: 1.16, seed: 7, samples: 140 })
      .forEach(({ d, i }) => groups[i % 3].push({ d, alpha: 0.18 - (i / 15) * 0.08, i }));
    const NS = 'http://www.w3.org/2000/svg';
    const layerClass = ['a', 'b', 'c'];
    groups.forEach((rings, gi) => {
      const par = document.createElementNS(NS, 'g');
      par.setAttribute('class', `topo-par topo-par--${layerClass[gi]}`);
      const drift = document.createElementNS(NS, 'g');
      drift.setAttribute('class', `topo-drift topo-drift--${layerClass[gi]}`);
      rings.forEach(({ d, alpha, i }) => {
        const p = document.createElementNS(NS, 'path');
        p.setAttribute('d', d);
        p.setAttribute('class', 'topo-ring' + (i >= 10 ? ' topo-ring--outer' : ''));
        p.setAttribute('fill', 'none');
        p.setAttribute('vector-effect', 'non-scaling-stroke');
        p.setAttribute('stroke-width', '1');
        if (i === 0) {
          p.setAttribute('stroke', 'var(--peach-400)');
          p.setAttribute('stroke-opacity', '0.5');
        } else {
          p.setAttribute('stroke', `rgba(14,14,12,${alpha.toFixed(3)})`);
        }
        p.style.setProperty('--ed', `${(0.35 + i * 0.09).toFixed(2)}s`);
        p.style.setProperty('--pd', `${(1.9 + i * 0.55).toFixed(2)}s`);
        drift.appendChild(p);
      });
      par.appendChild(drift);
      svg.appendChild(par);
    });
    const halo = document.createElementNS(NS, 'circle');
    halo.setAttribute('cx', CX);
    halo.setAttribute('cy', CY);
    halo.setAttribute('r', '4');
    halo.setAttribute('fill', 'none');
    halo.setAttribute('stroke', 'var(--peach-400)');
    halo.setAttribute('stroke-width', '1.5');
    halo.setAttribute('class', 'topo-halo');
    svg.appendChild(halo);

    const dot = document.createElementNS(NS, 'circle');
    dot.setAttribute('cx', CX);
    dot.setAttribute('cy', CY);
    dot.setAttribute('r', '3.2');
    dot.setAttribute('fill', 'var(--peach-400)');
    dot.setAttribute('class', 'topo-dot');
    svg.appendChild(dot);

    const root = rootRef.current;
    if (root && window.scrollY < 80 && !matchMedia('(prefers-reduced-motion: reduce)').matches) {
      root.classList.add('is-intro');
    }

    return () => {
      if (root) root.classList.remove('is-intro');
      while (svg.firstChild) svg.removeChild(svg.firstChild);
    };
  }, []);

  useEffect(() => {
    const root = rootRef.current;
    if (!root) return;
    if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    if (matchMedia('(pointer: coarse)').matches) return;
    const section = root.parentElement;
    const ruleX = root.querySelector('.topo-rule-x');
    const ruleY = root.querySelector('.topo-rule-y');
    const cross = root.querySelector('.topo-cross');

    let raf = null;
    let tx = 0, ty = 0, cx = 0, cy = 0;
    let px = 0, py = 0, ppx = 0, ppy = 0;

    const tick = () => {
      cx += (tx - cx) * 0.12;
      cy += (ty - cy) * 0.12;
      ppx += (px - ppx) * 0.07;
      ppy += (py - ppy) * 0.07;
      ruleX.style.transform = `translate3d(0, ${cy.toFixed(1)}px, 0)`;
      ruleY.style.transform = `translate3d(${cx.toFixed(1)}px, 0, 0)`;
      cross.style.transform = `translate3d(${cx.toFixed(1)}px, ${cy.toFixed(1)}px, 0)`;
      root.style.setProperty('--tpx', ppx.toFixed(3));
      root.style.setProperty('--tpy', ppy.toFixed(3));
      const converged = Math.abs(tx - cx) < 0.1 && Math.abs(ty - cy) < 0.1 &&
        Math.abs(px - ppx) < 0.001 && Math.abs(py - ppy) < 0.001;
      raf = converged ? null : requestAnimationFrame(tick);
    };
    const kick = () => { if (!raf) raf = requestAnimationFrame(tick); };
    const onMove = (e) => {
      tx = e.clientX;
      ty = e.clientY;
      px = (e.clientX / window.innerWidth) * 2 - 1;
      py = (e.clientY / window.innerHeight) * 2 - 1;
      root.classList.add('is-pointing');
      kick();
    };
    const onLeave = () => { root.classList.remove('is-pointing'); };
    section.addEventListener('pointermove', onMove, { passive: true });
    section.addEventListener('pointerleave', onLeave, { passive: true });
    return () => {
      section.removeEventListener('pointermove', onMove);
      section.removeEventListener('pointerleave', onLeave);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  useEffect(() => {
    const root = rootRef.current;
    if (!root) return;
    const hero = root.parentElement;
    const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches;

    let raf = null;
    const onScroll = () => {
      if (reduced || raf) return;
      raf = requestAnimationFrame(() => {
        raf = null;
        root.style.setProperty('--tsy', (window.scrollY * -0.08).toFixed(1));
        root.style.setProperty('--tty', (window.scrollY * -TRAIL_RATE).toFixed(1));
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();

    const heroIO = new IntersectionObserver(([e]) => {
      root.classList.toggle('is-dimmed', !e.isIntersecting);
    }, { threshold: 0 });
    heroIO.observe(hero);

    return () => {
      window.removeEventListener('scroll', onScroll);
      if (raf) cancelAnimationFrame(raf);
      heroIO.disconnect();
    };
  }, []);

  useEffect(() => {
    const trail = trailRef.current;
    if (!trail) return;
    const NS = 'http://www.w3.org/2000/svg';
    let built = { w: 0, h: 0 };
    let timer = null;

    const build = () => {
      const w = window.innerWidth;
      const vh = window.innerHeight;
      const docH = document.documentElement.scrollHeight;
      const mapH = Math.ceil(vh + Math.max(0, docH - vh) * TRAIL_RATE + vh * 0.4);
      if (w === built.w && Math.abs(mapH - built.h) < 120) return;
      built = { w, h: mapH };
      while (trail.firstChild) trail.removeChild(trail.firstChild);
      trail.setAttribute('viewBox', `0 0 ${w} ${mapH}`);
      trail.style.height = `${mapH}px`;

      const reach = Math.max(vh, 640) * 0.42;
      let seed = 23;
      const rand = () => (seed = (seed * 16807) % 2147483647) / 2147483647;
      let y = vh * 1.2;
      let side = 0;
      while (y < mapH + reach * 0.5) {
        const x = w * (side % 2 === 0 ? 0.14 + rand() * 0.12 : 0.74 + rand() * 0.12);
        const count = 11;
        const r0 = reach / Math.pow(1.24, count - 1);
        topoRingPaths({ cx: x, cy: y, r0, count, growth: 1.24, seed: 101 + side * 7, samples: 120 })
          .forEach(({ d, i }) => {
            const p = document.createElementNS(NS, 'path');
            p.setAttribute('d', d);
            p.setAttribute('fill', 'none');
            p.setAttribute('vector-effect', 'non-scaling-stroke');
            p.setAttribute('stroke-width', '1');
            if (i === 0) {
              p.setAttribute('stroke', 'var(--peach-400)');
              p.setAttribute('stroke-opacity', '0.35');
            } else {
              p.setAttribute('stroke', `rgba(14,14,12,${(0.1 - (i / (count - 1)) * 0.06).toFixed(3)})`);
            }
            trail.appendChild(p);
          });
        y += vh * (0.8 + rand() * 0.25);
        side++;
      }
    };
    const schedule = () => { clearTimeout(timer); timer = setTimeout(build, 200); };

    build();
    const ro = new ResizeObserver(schedule);
    ro.observe(document.body);
    window.addEventListener('resize', schedule, { passive: true });
    return () => {
      clearTimeout(timer);
      ro.disconnect();
      window.removeEventListener('resize', schedule);
      while (trail.firstChild) trail.removeChild(trail.firstChild);
    };
  }, []);

  return (
    <div className="topo-field" ref={rootRef} aria-hidden="true">
      <svg ref={trailRef} className="topo-trail" preserveAspectRatio="none"></svg>
      <svg ref={svgRef} className="topo-main" viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid slice"></svg>
      <div className="topo-reticle">
        <div className="topo-rule-x"></div>
        <div className="topo-rule-y"></div>
        <div className="topo-cross"></div>
      </div>
    </div>
  );
}

/* ======================= Hero ======================= */
function Hero() {
  return (
    <section id="top" style={{
      position: 'relative',
      padding: 'clamp(120px, 16vw, 180px) 0 clamp(80px, 10vw, 120px)',
      overflow: 'hidden'
    }}>
      <TopoField />

      <div className="container" style={{ position: 'relative', zIndex: 1 }}>
        <span className="chip chip--peach reveal" style={{ marginBottom: 32 }}>
          <span className="chip__dot"></span>GTM Engineering · Growth Marketing
        </span>

        <h1 className="display-serif reveal" style={{
          fontSize: 'clamp(52px, 9vw, 128px)',
          margin: 0,
          maxWidth: 1080,
          paddingBottom: '0.06em'
        }}>
          On amorce votre <RotatingWord words={HERO_WORDS} />
          <br />
          <em>Vous accélérez.</em>
        </h1>

        <p className="reveal" style={{
          fontFamily: 'var(--font-sans)',
          fontSize: 'clamp(18px, 1.6vw, 22px)',
          lineHeight: 1.5,
          color: 'var(--fg-2)',
          maxWidth: 620,
          margin: '32px 0 48px'
        }}>On construit les systèmes qui transforment vos prospects en clients, et chaque client en relation durable. 
On conçoit, on forme, vous opérez.

        </p>

        <div className="reveal" style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
          <Button variant="accent" href="#rdv">Prendre rendez-vous</Button>
          <Button variant="ghost" href="#methode" icon="↓">Découvrir la méthode</Button>
        </div>
      </div>

      <div className="scroll-hint" aria-hidden="true">
        <span>scroll</span>
        <div className="scroll-hint__line"></div>
      </div>
    </section>);

}

/* ======================= Problème ======================= */
function Problem() {
  const pains = [
  "Votre acquisition repose sur des coups, pas sur un système qui génère des leads qualifiés en continu.",
  <>Vous gagnez des clients, mais leur expérience <span style={{ whiteSpace: 'nowrap' }}>après-vente</span> ne génère ni fidélité ni upsell.</>,
  "Vos équipes passent un temps fou sur des tâches répétitives au lieu de se concentrer sur ce qui a vraiment de la valeur."];

  const painColors = ['var(--peach-100)', 'var(--lilac)', 'var(--mint)'];
  const sectionRef = useRef(null);

  useEffect(() => {
    if (!window.gsap || !window.ScrollTrigger) return;
    gsap.registerPlugin(ScrollTrigger);
    const section = sectionRef.current;
    const mm = gsap.matchMedia();

    mm.add('(min-width: 768px) and (min-height: 700px) and (prefers-reduced-motion: no-preference)', () => {
      section.classList.add('is-pinned-scene');
      const items = gsap.utils.toArray('.pain-slide', section);
      const blocks = gsap.utils.toArray('.pain-slide__block', section);
      const dots = gsap.utils.toArray('.pain-progress__dot', section);
      const closing = section.querySelector('.pain-closing');

      gsap.set(items, { autoAlpha: 0, y: 24 });
      gsap.set(items[0], { autoAlpha: 1, y: 0 });
      gsap.set(blocks, { scaleX: 0 });
      gsap.set(closing, { autoAlpha: 0.25 });

      const tl = gsap.timeline({
        defaults: { ease: 'none' },
        scrollTrigger: {
          trigger: section,
          start: 'top top',
          end: '+=320%',
          pin: true,
          scrub: 1,
          onUpdate: () => {
            const idx = items.reduce((acc, el, i) => (gsap.getProperty(el, 'autoAlpha') > 0.5 ? i : acc), 0);
            dots.forEach((d, i) => d.classList.toggle('is-on', i === idx));
          }
        }
      });

      for (let i = 0; i < 2; i++) {
        tl.to({}, { duration: 1 })
          .to(items[i], { autoAlpha: 0, y: -24, duration: 0.8, ease: 'power1.inOut' })
          .fromTo(blocks[i + 1],
            { scaleX: 0, transformOrigin: 'left center' },
            { scaleX: 1, duration: 0.9, ease: 'power1.inOut' })
          .set(items[i + 1], { autoAlpha: 1, y: 0 })
          .to(blocks[i + 1], { scaleX: 0, transformOrigin: 'right center', duration: 0.9, ease: 'power1.inOut' });
      }
      tl.to(closing, { autoAlpha: 1, duration: 0.8 })
        .to({}, { duration: 0.6 });

      return () => {
        section.classList.remove('is-pinned-scene');
      };
    });

    return () => mm.revert();
  }, []);

  return (
    <section className="section" ref={sectionRef}>
      <div className="container">
        <span className="chip chip--paper reveal" style={{ marginBottom: 28 }}>
          <span className="chip__dot"></span>Constat
        </span>
        <h2 className="display-serif reveal" style={{
          fontSize: 'clamp(36px, 5vw, 64px)', margin: '28px 0 0', maxWidth: 780
        }}>
          Une croissance prévisible n'arrive pas par <em>hasard</em>.
        </h2>

        <div className="pain-stage">
          {pains.map((p, i) =>
          <div key={i} className="pain-slide">
              <span className="pain-item__n">0{i + 1}</span>
              <p className="pain-slide__text">{p}</p>
              <div className="pain-slide__block" style={{ background: painColors[i] }}></div>
            </div>
          )}
        </div>

        <div className="pain-progress" aria-hidden="true">
          <span className="pain-progress__dot"></span>
          <span className="pain-progress__dot"></span>
          <span className="pain-progress__dot"></span>
        </div>

        <p className="pain-closing reveal" style={{
          fontFamily: 'var(--font-serif)',
          fontSize: 'clamp(22px, 2.3vw, 30px)',
          lineHeight: 1.3,
          fontStyle: 'italic',
          color: 'var(--ink)',
          margin: '0',
          maxWidth: 640
        }}>
          On amorce le système. Vous l'opérez ensuite.
        </p>
      </div>
    </section>);

}

/* ======================= Expertise ======================= */
function Expertise() {
  const groups = [
  {
    key: 'gtm',
    tag: '01',
    title: 'GTM Strategy\n& Engineering',
    sub: 'Acquérir de nouveaux clients',
    items: [
    'Product marketing : positionnement, ICP, personas',
    'Enrichissement de données, signaux d\'achat',
    'TAM mapping, segmentation, scoring',
    'Séquences outbound multicanales']

  },
  {
    key: 'user',
    tag: '02',
    title: 'User\nMarketing',
    sub: 'Fidéliser et développer vos clients',
    items: [
    'Onboarding client automatisé',
    'Emails cycle de vie et nurturing',
    'Product releases et communication produit',
    'Base de connaissance et documentation client']

  },
  {
    key: 'ops',
    tag: '03',
    title: 'Automatisation\n& IA',
    sub: 'Gagner du temps et de la visibilité',
    items: [
    'Systèmes de production de contenu automatisés (articles, visuels, posts LinkedIn, landing pages)',
    'Reporting et dashboards automatisés',
    'Veille concurrentielle et sectorielle',
    'Applications internes no-code / low-code']

  }];


  return (
    <section id="expertise" className="section">
      <div className="container">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 32, flexWrap: 'wrap', marginBottom: 72 }}>
          <div>
            <span className="chip chip--paper reveal" style={{ marginBottom: 20 }}>
              <span className="chip__dot"></span>Expertise
            </span>
            <h2 className="display-serif reveal" style={{
              fontSize: 'clamp(36px, 5vw, 64px)', margin: 0, maxWidth: 820
            }}>
              Une expérience prospect <br />
              et client <em>de bout en bout</em>.
            </h2>
          </div>
        </div>

        <div className="expertise-grid reveal-stagger" style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          gap: 56
        }}>
          {groups.map((g, gi) => {
            const chipVariants = ['peach', 'lilac', 'mint'];
            return (
              <div key={g.key} className="expertise-col">
                <span className={`chip chip--${chipVariants[gi]}`} style={{ marginBottom: 20, alignSelf: 'flex-start' }}>
                  <span className="chip__dot"></span>Pôle · {g.tag}
                </span>
                <h4 style={{ whiteSpace: 'pre-line', marginTop: 12 }}>{g.title}</h4>
                <p style={{
                  fontFamily: 'var(--font-serif)', fontStyle: 'italic',
                  fontSize: 17, lineHeight: 1.3, color: 'var(--fg-3)',
                  margin: '4px 0 8px'
                }}>{g.sub}</p>
                <ul>
                  {g.items.map((it, i) => <li key={i}>{it}</li>)}
                </ul>
              </div>);

          })}
        </div>
      </div>
    </section>);

}

Object.assign(window, { Hero, Problem, Expertise });