// Atelier — atoms : cursor, nav, footer, signature thread, hooks, forms

const { useState, useEffect, useRef, useMemo, useLayoutEffect } = React;

/* =========================================================
   useRoute — simple hash router (#/ and #/immobilier)
   ========================================================= */
function useRoute() {
  const [route, setRoute] = useState(() => window.location.hash.replace('#', '') || '/');
  useEffect(() => {
    const onHash = () => setRoute(window.location.hash.replace('#', '') || '/');
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  return [route, (r) => { window.location.hash = r; }];
}


/* =========================================================
   Reveal — IntersectionObserver fade-up
   ========================================================= */
function Reveal({ children, delay = 0, as: As = 'div', ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    // Immediate check
    const rect = el.getBoundingClientRect();
    if (rect.top < window.innerHeight && rect.bottom > 0) {
      setShown(true);
      return;
    }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setShown(true); io.disconnect(); }
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    io.observe(el);
    const fallback = setTimeout(() => setShown(true), 2500);
    return () => { io.disconnect(); clearTimeout(fallback); };
  }, []);
  return (
    <As ref={ref} className={`reveal ${shown ? 'in' : ''} ${rest.className || ''}`} style={{ transitionDelay: `${delay}ms`, ...(rest.style || {}) }}>
      {children}
    </As>
  );
}

/* =========================================================
   RevealText — split into words/chars with staggered reveal
   ========================================================= */
function RevealText({ text, as: As = 'span', stagger = 28, mode = 'word', className = '', delay = 0 }) {
  const parts = mode === 'char' ? text.split('') : text.split(' ');
  return (
    <As className={`rt ${className}`}>
      {parts.map((p, i) => (
        <React.Fragment key={i}>
          <span className="rt-word">
            <span
              className="rt-inner rt-anim"
              style={{ animationDelay: `${delay + i * stagger}ms` }}
            >{p === ' ' ? '\u00A0' : p}</span>
          </span>
          {mode === 'word' && i < parts.length - 1 ? '\u00A0' : null}
        </React.Fragment>
      ))}
    </As>
  );
}

/* =========================================================
   RotatingWord — fluid morphing word for hero
   ========================================================= */
function RotatingWord({ words, interval = 2200 }) {
  const [i, setI] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setI(v => (v + 1) % words.length), interval);
    return () => clearInterval(id);
  }, [words.length, interval]);
  // Measure widest word so the slot doesn't jump
  const measureRef = useRef(null);
  const [w, setW] = useState(0);
  useLayoutEffect(() => {
    if (!measureRef.current) return;
    const widths = Array.from(measureRef.current.children).map(c => c.getBoundingClientRect().width);
    setW(Math.max(...widths));
  }, [words]);
  return (
    <span className="rotw" style={{ width: w ? `${w}px` : 'auto' }}>
      <span className="rotw-measure" ref={measureRef} aria-hidden="true">
        {words.map((wd, k) => <span key={k}>{wd}</span>)}
      </span>
      {words.map((wd, k) => (
        <span key={k} className={`rotw-item ${k === i ? 'is-current' : k === (i - 1 + words.length) % words.length ? 'is-prev' : ''}`}>
          {wd}
        </span>
      ))}
    </span>
  );
}

/* =========================================================
   Marquee — single direction, infinite
   ========================================================= */
function Marquee({ children, speed = 60, reverse = false }) {
  return (
    <div className="marquee" data-reverse={reverse ? 'true' : 'false'}>
      <div className="marquee-track" style={{ animationDuration: `${speed}s` }}>
        <div className="marquee-content">{children}</div>
        <div className="marquee-content" aria-hidden="true">{children}</div>
        <div className="marquee-content" aria-hidden="true">{children}</div>
        <div className="marquee-content" aria-hidden="true">{children}</div>
      </div>
    </div>
  );
}

/* =========================================================
   Signature — corner coordinate labels (style Édition)
   ========================================================= */
function SignatureThread() {
  return (
    <div className="signature" aria-hidden="true">
      <span className="g-mark g-tl">NF · 01</span>
      <span className="g-mark g-tr">Studio · Digital</span>
      <span className="g-mark g-bl">Haute-Goulaine · Nantes</span>
      <span className="g-mark g-br">© 2026</span>
    </div>
  );
}

/* =========================================================
   Logo — image-based (remplacer assets/logo-noir.png)
   ========================================================= */
function Logo({ small }) {
  return (
    <a href="#/" className={`logo ${small ? 'logo-sm' : ''}`} aria-label="NeoFlow Agency — Accueil">
      <span className="logo-mark" aria-hidden="true">
        <span className="logo-img" role="img"></span>
      </span>
    </a>
  );
}

/* =========================================================
   Nav — sticky, with sections links
   ========================================================= */
function Nav({ route, setRoute }) {
  const homeLinks = [
    ['#services', 'Services'],
    ['#process', 'Process'],
    ['#noakim', 'À propos'],
    ['#faq', 'FAQ'],
    ['#contact', 'Contact'],
  ];
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 24);
    window.addEventListener('scroll', on, { passive: true });
    on();
    return () => window.removeEventListener('scroll', on);
  }, []);

  const isImmo = route === '/immobilier';

  return (
    <nav className={`nav ${scrolled ? 'is-scrolled' : ''} ${isImmo ? 'nav-immo' : ''}`}>
      <div className="nav-inner wrap">
        <Logo />
        <div className="nav-links">
          {isImmo ? (
            <>
              <a href="#/" onClick={(e) => { e.preventDefault(); setRoute('/'); }}>← Accueil</a>
              <button className="nav-link-immo" onClick={() => setRoute('/immo/repondre')}>Répondre</button>
              <button className="nav-link-immo" onClick={() => setRoute('/immo/question')}>Poser une question</button>
            </>
          ) : (
            <>
              {homeLinks.map(([href, label]) => (
                <a key={href} href={href}>{label}</a>
              ))}
              <a
                href="#/immobilier"
                className="nav-link-immo"
                onClick={(e) => { e.preventDefault(); setRoute('/immobilier'); }}
              >NeoFlow Immo</a>
            </>
          )}
        </div>
        <div className="nav-right">
          {isImmo ? (
            <button className="nav-cta" onClick={() => { window.posthog && window.posthog.capture('nav_cta_click', { page: 'immobilier' }); setRoute('/immo/repondre'); }}>
              <span>Répondre aux questions</span>
              <svg width="12" height="10" viewBox="0 0 14 10" fill="none"><path d="M1 5h12m0 0L9 1m4 4L9 9" stroke="currentColor" strokeWidth="1.2"/></svg>
            </button>
          ) : (
            <button className="nav-cta" onClick={() => { window.posthog && window.posthog.capture('nav_cta_click', { page: 'home' }); setRoute('/demarrer'); }}>
              <span>Démarrer un projet</span>
              <svg width="12" height="10" viewBox="0 0 14 10" fill="none"><path d="M1 5h12m0 0L9 1m4 4L9 9" stroke="currentColor" strokeWidth="1.2"/></svg>
            </button>
          )}
        </div>
      </div>
    </nav>
  );
}

/* =========================================================
   Footer
   ========================================================= */
function Footer({ setRoute }) {
  return (
    <footer className="footer">
      <div className="wrap footer-grid">
        <div className="footer-col">
          <Logo />
          <p className="footer-tag">On développe vos outils. Vous, votre métier.</p>
        </div>
        <div className="footer-col">
          <div className="footer-h">Pages</div>
          <a href="#services">Services</a>
          <a href="#process">Process</a>
          <a href="#noakim">À propos</a>
          <a href="#faq">FAQ</a>
          <a href="#contact">Contact</a>
          <a href="#/immobilier" onClick={() => setRoute('/immobilier')}>Immobilier</a>
        </div>
        <div className="footer-col">
          <div className="footer-h">Contact</div>
          <a href="mailto:contact@neoflow-agency.cloud">contact@neoflow-agency.cloud</a>
          <a href="https://instagram.com/neoflow_agency">Instagram @neoflow_agency</a>
          <span className="muted">Réponse sous 24h</span>
        </div>
        <div className="footer-col">
          <div className="footer-h">Studio</div>
          <span className="muted">Noakim Grelier</span>
          <span className="muted">Haute-Goulaine · Nantes</span>
          <span className="muted">France</span>
        </div>
      </div>
      <div className="wrap footer-bottom">
        <div>© 2026 NeoFlow Agency</div>
        <div className="footer-bottom-right">
          <a href="#/mentions-legales" onClick={(e) => { e.preventDefault(); setRoute('/mentions-legales'); }}>Mentions légales</a>
          <a href="#/confidentialite" onClick={(e) => { e.preventDefault(); setRoute('/confidentialite'); }}>Politique de confidentialité</a>
        </div>
      </div>
    </footer>
  );
}

/* =========================================================
   CookieConsent — bannière RGPD avec panel de préférences
   ========================================================= */
function CookieConsent() {
  const [visible, setVisible] = useState(false);
  const [mode, setMode] = useState('banner');
  const [prefs, setPrefs] = useState({ analytics: false, recording: false, marketing: false, email: false });

  useEffect(() => {
    if (!localStorage.getItem('nf-consent')) setVisible(true);
  }, []);

  // Auto-refuse si l'utilisateur scrolle sans répondre
  useEffect(() => {
    if (!visible) return;
    function onScroll() {
      if (window.scrollY > 300) { refuse(); }
    }
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, [visible]);

  function applyPrefs(p) {
    if (p.analytics) { if (window.posthog) window.posthog.opt_in_capturing(); }
    else { if (window.posthog) window.posthog.opt_out_capturing(); }
    if (p.analytics && p.recording) { if (window.posthog && window.posthog.startSessionRecording) window.posthog.startSessionRecording(); }
    else { if (window.posthog && window.posthog.stopSessionRecording) window.posthog.stopSessionRecording(); }
  }

  function accept() {
    const p = { analytics: true, recording: true, marketing: false, email: false };
    localStorage.setItem('nf-consent', 'accepted');
    localStorage.setItem('nf-consent-prefs', JSON.stringify(p));
    applyPrefs(p);
    setVisible(false);
  }
  function refuse() {
    const p = { analytics: false, recording: false, marketing: false, email: false };
    localStorage.setItem('nf-consent', 'refused');
    localStorage.setItem('nf-consent-prefs', JSON.stringify(p));
    applyPrefs(p);
    setVisible(false);
  }
  function saveCustom() {
    localStorage.setItem('nf-consent', 'custom');
    localStorage.setItem('nf-consent-prefs', JSON.stringify(prefs));
    applyPrefs(prefs);
    setVisible(false);
  }
  function togglePref(key) { setPrefs(p => ({ ...p, [key]: !p[key] })); }

  if (!visible) return null;

  const PREFS_DEF = [
    { key: 'analytics',  label: 'Analytics',         desc: 'Mesure d\'audience, pages vues, événements (PostHog EU Cloud, Francfort)' },
    { key: 'recording',  label: 'Session recording',  desc: 'Enregistrements anonymisés de navigation — PostHog Replay' },
    { key: 'marketing',  label: 'Marketing',          desc: 'Publicité ciblée et remarketing — non actif actuellement', inactive: true },
    { key: 'email',      label: 'Email marketing',    desc: 'Newsletters et communications commerciales — non actif', inactive: true },
  ];

  return (
    <div className="cookie-overlay">
      <div className="cookie-panel" role="dialog" aria-modal="true" aria-label="Préférences de confidentialité">
        <div className="cookie-panel-inner">
          {mode === 'banner' ? (
            <>
              <div className="cookie-banner-content">
                <p className="cookie-banner-title">Vos préférences de confidentialité</p>
                <p className="cookie-banner-text">
                  Nous utilisons PostHog (EU Cloud) pour analyser le trafic et améliorer l'expérience — aucun cookie publicitaire, aucune revente de données.{' '}
                  <a href="#/confidentialite" onClick={(e) => { e.preventDefault(); window.location.hash = '/confidentialite'; refuse(); }}>Politique de confidentialité</a>
                </p>
              </div>
              <div className="cookie-banner-actions">
                <button className="cookie-btn cookie-btn-refuse" onClick={refuse}>Refuser</button>
                <button className="cookie-btn cookie-btn-settings" onClick={() => setMode('settings')}>Paramétrer</button>
                <button className="cookie-btn cookie-btn-accept" onClick={accept}>Accepter</button>
              </div>
            </>
          ) : (
            <>
              <div className="cookie-settings-header">
                <button className="cookie-back" onClick={() => setMode('banner')}>← Retour</button>
                <p className="cookie-settings-title">Paramétrer les cookies</p>
              </div>
              <div className="cookie-settings-list">
                {PREFS_DEF.map(({ key, label, desc, inactive }) => (
                  <div key={key} className={`cookie-pref-row ${inactive ? 'is-inactive' : ''}`}>
                    <div className="cookie-pref-info">
                      <span className="cookie-pref-label">{label}</span>
                      <span className="cookie-pref-desc">{desc}</span>
                    </div>
                    <button
                      className={`cookie-toggle ${prefs[key] ? 'is-on' : ''}`}
                      onClick={() => !inactive && togglePref(key)}
                      aria-pressed={prefs[key]}
                      disabled={!!inactive}
                    >
                      <span className="cookie-toggle-knob"></span>
                    </button>
                  </div>
                ))}
              </div>
              <div className="cookie-banner-actions">
                <button className="cookie-btn cookie-btn-refuse" onClick={refuse}>Tout refuser</button>
                <button className="cookie-btn cookie-btn-accept" onClick={saveCustom}>Confirmer mes choix</button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  useRoute,
  Reveal, RevealText, RotatingWord, Marquee,
  SignatureThread, Logo, Nav, Footer,
  CookieConsent,
});
