const QDS = () => window.QuintescenceDesignSystem_dab9ce;
const KEY = '#641124';
const TP = n => `assets/papier/tornpaper${n}.webp`;

// ---------- Logo officiel, animé en permanence ----------
let logoCache = null;
async function loadLogo() {
  if (logoCache) return logoCache;
  const txt = await (await fetch('assets/logo/logo-officiel.svg')).text();
  const doc = new DOMParser().parseFromString(txt, 'image/svg+xml');
  const svg = doc.documentElement;
  svg.querySelectorAll('metadata,defs').forEach(n => n.remove());
  const firstX = el => { const d = el.getAttribute('d'); if (d) return parseFloat(d.slice(1)); return parseFloat(el.getAttribute('x') || el.getAttribute('cx') || 0); };
  const letters = [];
  [...svg.children].forEach(el => {
    const d = el.getAttribute('d') || '';
    if (el.tagName === 'g') { el.setAttribute('class', el.innerHTML.includes('M246.12') ? 'lq' : 'ltag'); return; }
    if (d.startsWith('M273.99')) return el.setAttribute('class', 'lq');
    if (d.startsWith('M1277')) return el.setAttribute('class', 'lstar');
    if (d.startsWith('M1849')) return el.setAttribute('class', 'lflower');
    if (d.startsWith('M1840')) return el.setAttribute('class', 'lpetal');
    if (el.tagName === 'ellipse') return el.setAttribute('class', +el.getAttribute('ry') > 20 ? 'ldot' : 'lbullet');
    if (d.startsWith('M1196')) return el.setAttribute('class', 'lbullet');
    letters.push(el);
  });
  letters.sort((a, b) => firstX(a) - firstX(b)).forEach((el, i) => {
    el.setAttribute('class', 'lt'); el.setAttribute('style', `--i:${i}`);
    const f = el.getAttribute('fill'), x = firstX(el);
    if (f === '#6E0A2A') el.setAttribute('fill', x < 1000 ? '#F9D3DC' : '#F5A9C8');
    if (el.tagName === 'rect') el.setAttribute('fill', '#F9D3DC');
  });
  svg.querySelectorAll('.lq[fill="#6B022D"], .lq [fill="#6B022D"]').forEach(p => p.setAttribute('fill', '#F8B4CF'));
  svg.querySelectorAll('.ltag [fill="#6B022D"]').forEach(p => p.setAttribute('fill', '#FFF8EC'));
  svg.querySelectorAll('.ltag').forEach((g, i) => g.setAttribute('style', `--i:${i}`));
  svg.removeAttribute('id');
  svg.setAttribute('class', 'qlogo'); svg.setAttribute('role', 'img'); svg.setAttribute('aria-label', 'Quintescence — Bijoux, Accessoires, Vêtements');
  logoCache = new XMLSerializer().serializeToString(svg);
  return logoCache;
}
function AnimatedLogo({ style, className = '' }) {
  const [svg, setSvg] = React.useState(logoCache);
  React.useEffect(() => { if (!svg) loadLogo().then(setSvg); }, []);
  return <div className={'qlogo-wrap ' + className} style={style} dangerouslySetInnerHTML={{ __html: svg || '' }}></div>;
}

// ---------- Moteur de scroll ----------
function useScrollEngine(deps = []) {
  React.useEffect(() => {
    let raf;
    const pins = () => document.querySelectorAll('[data-pin]');
    const pars = () => document.querySelectorAll('[data-par]');
    let key = '';
    const tick = () => {
      const vh = innerHeight, sh = document.documentElement.scrollHeight;
      const k = scrollY + '|' + vh + '|' + sh;
      if (k === key) { raf = requestAnimationFrame(tick); return; }
      key = k;
      const max = sh - vh, bar = document.querySelector('.progress');
      if (bar) bar.style.transform = 'scaleX(' + (max > 0 ? scrollY / max : 0).toFixed(4) + ')';
      pins().forEach(el => {
        const r = el.getBoundingClientRect();
        const p = Math.max(0, Math.min(1, -r.top / Math.max(1, r.height - vh)));
        el.style.setProperty('--p', p.toFixed(4));
      });
      pars().forEach(el => {
        const r = el.getBoundingClientRect();
        const off = (r.top + r.height / 2 - vh / 2) / vh;
        el.style.setProperty('--o', off.toFixed(4));
      });
      raf = requestAnimationFrame(tick);
    };
    tick();
    const io = new IntersectionObserver(es => es.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); } }), { threshold: 0.18 });
    const scan = () => document.querySelectorAll('[data-reveal]:not([data-obs]),[data-words]:not([data-obs])').forEach(el => { el.setAttribute('data-obs', ''); io.observe(el); });
    scan();
    const mo = new MutationObserver(scan); mo.observe(document.body, { childList: true, subtree: true });
    return () => { cancelAnimationFrame(raf); io.disconnect(); mo.disconnect(); };
  }, deps);
}

// Texte révélé mot à mot
function Words({ text, as = 'span', style, className = '', step = 0.04 }) {
  const T = as;
  return <T data-words="" className={'words ' + className} style={style}>{text.split(' ').map((w, i) => <React.Fragment key={i}><span className="w" style={{ '--d': (i * step).toFixed(2) + 's' }}><span>{w}</span></span>{' '}</React.Fragment>)}</T>;
}

// Papier déchiré en image (webp) teinté
function Paper({ n = 4, color, children, style, className = '', ...rest }) {
  const bg = color ? { background: `${color} url(${TP(n)}) center/100% 100% no-repeat`, backgroundBlendMode: 'multiply', WebkitMask: `url(${TP(n)}) center/100% 100% no-repeat`, mask: `url(${TP(n)}) center/100% 100% no-repeat` } : { background: `url(${TP(n)}) center/100% 100% no-repeat` };
  return <div className={'paper ' + className} style={style} {...rest}><div style={{ ...bg, height: '100%' }}>{children}</div></div>;
}
function Tape({ n = 7, style }) { return <span aria-hidden="true" className="tape" style={{ background: `url(assets/papier/tape${n}.webp) center/100% 100% no-repeat`, ...style }}></span>; }

function Eyebrow({ children, color = 'var(--q-peach)', style }) {
  return <div style={{ font: '500 12px var(--font-sub)', letterSpacing: 'var(--ls-eyebrow)', textTransform: 'uppercase', color, ...style }}>{children}</div>;
}

const euro = n => n.toFixed(2).replace('.', ',') + '\u00a0€';
const vt = fn => (document.startViewTransition ? document.startViewTransition(fn) : fn());

Object.assign(window, { QDS, KEY, TP, AnimatedLogo, loadLogo, useScrollEngine, Words, Paper, Tape, Eyebrow, euro, vt });
