/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

/* ========================= A11Y WIDGET ========================= */
const A11Y_DEFAULTS = {
  fontSize: 100,       // percent
  letterSpacing: 0,    // em * 100
  lineHeight: 155,     // 100-250
  contrast: 'normal',  // normal | high | dark
  colorblind: 'none',  // none | protanopia | deuteranopia | tritanopia | monochrome
  dyslexia: false,
  motion: 'normal',    // normal | reduce
  links: false,
  cursor: 'normal',    // normal | big
  guide: false,
  tts: false,
};

function applyA11Y(s) {
  const root = document.documentElement;
  root.style.setProperty('--fs-root', (16 * s.fontSize / 100) + 'px');
  root.style.setProperty('--ls', (s.letterSpacing / 100) + 'em');
  root.style.setProperty('--lh', (s.lineHeight / 100).toString());
  if (s.contrast === 'normal') root.removeAttribute('data-a11y-contrast');
  else root.setAttribute('data-a11y-contrast', s.contrast);
  if (s.colorblind === 'none') root.removeAttribute('data-a11y-colorblind');
  else root.setAttribute('data-a11y-colorblind', s.colorblind);
  root.setAttribute('data-a11y-dyslexia', s.dyslexia ? 'true' : 'false');
  root.setAttribute('data-a11y-motion', s.motion);
  root.setAttribute('data-a11y-links', s.links ? 'true' : 'false');
  root.setAttribute('data-a11y-cursor', s.cursor);
  root.setAttribute('data-a11y-guide', s.guide ? 'true' : 'false');
}

function useA11Y() {
  const [s, setS] = useState(() => {
    try { return { ...A11Y_DEFAULTS, ...JSON.parse(localStorage.getItem('yo-a11y') || '{}') }; }
    catch { return A11Y_DEFAULTS; }
  });
  useEffect(() => {
    applyA11Y(s);
    localStorage.setItem('yo-a11y', JSON.stringify(s));
  }, [s]);
  return [s, setS];
}

function Icon({ name, size = 18 }) {
  const icons = {
    wheelchair: <><circle cx="12" cy="4" r="2"/><path d="M12 6v8M12 14l-3 6M12 14l3 0a5 5 0 0 1 5 5"/></>,
    close: <><path d="M6 6L18 18M18 6L6 18"/></>,
    sun: <><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></>,
    moon: <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>,
    contrast: <><circle cx="12" cy="12" r="10"/><path d="M12 2v20M2 12h20" fill="currentColor"/></>,
    eye: <><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></>,
    type: <><path d="M4 7V4h16v3M9 20h6M12 4v16"/></>,
    cursor: <path d="M3 2l0 16 5-5 3 8 3-1-3-8 7 0z"/>,
    link: <><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1"/><path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></>,
    motion: <><path d="M12 2v6M12 16v6M4.93 4.93l4.24 4.24M14.83 14.83l4.24 4.24M2 12h6M16 12h6M4.93 19.07l4.24-4.24M14.83 9.17l4.24-4.24"/></>,
    read: <><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></>,
    palette: <><circle cx="13.5" cy="6.5" r="1"/><circle cx="17.5" cy="10.5" r="1"/><circle cx="8.5" cy="7.5" r="1"/><circle cx="6.5" cy="12.5" r="1"/><path d="M12 2a10 10 0 1 0 10 10h-4a2 2 0 0 0-2 2 2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2 2 2 0 0 0-2-2H4a10 10 0 0 1 8-10z"/></>,
    speaker: <><path d="M11 5L6 9H2v6h4l5 4z"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/></>,
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">{icons[name]}</svg>;
}

function A11YWidget() {
  const [s, setS] = useA11Y();
  const [open, setOpen] = useState(false);

  const upd = (k, v) => setS({ ...s, [k]: v });
  const toggle = k => upd(k, !s[k]);
  const reset = () => setS(A11Y_DEFAULTS);

  const ttsRead = () => {
    if (!('speechSynthesis' in window)) { alert("Synthèse vocale non supportée."); return; }
    if (speechSynthesis.speaking) { speechSynthesis.cancel(); return; }
    const text = document.querySelector('main')?.innerText?.slice(0, 3000) || '';
    const u = new SpeechSynthesisUtterance(text);
    u.lang = 'fr-FR'; u.rate = 1;
    speechSynthesis.speak(u);
  };

  return (
    <>
      <button className="a11y-fab" aria-label="Ouvrir le menu d'accessibilité" onClick={() => setOpen(!open)}>
        <Icon name="wheelchair" size={26} />
        <span className="a11y-fab-label">Accessibilité</span>
      </button>
      <div className={"a11y-panel" + (open ? " open" : "")} role="dialog" aria-label="Options d'accessibilité">
        <div className="a11y-head">
          <div>
            <div className="sub">Accessibilité</div>
            <h3>Adaptez l'affichage</h3>
          </div>
          <button className="a11y-close" onClick={() => setOpen(false)} aria-label="Fermer"><Icon name="close" /></button>
        </div>
        <div className="a11y-body">

          <div className="a11y-group">
            <div className="a11y-group-label">Taille du texte</div>
            <div className="a11y-slider">
              <span className="lbl">Texte</span>
              <span className="val">{s.fontSize}%</span>
              <div className="stepper">
                <button onClick={() => upd('fontSize', Math.max(80, s.fontSize - 10))}>−</button>
                <button onClick={() => upd('fontSize', Math.min(180, s.fontSize + 10))}>+</button>
              </div>
            </div>
            <div className="a11y-slider">
              <span className="lbl">Interligne</span>
              <span className="val">{(s.lineHeight/100).toFixed(1)}</span>
              <div className="stepper">
                <button onClick={() => upd('lineHeight', Math.max(100, s.lineHeight - 15))}>−</button>
                <button onClick={() => upd('lineHeight', Math.min(250, s.lineHeight + 15))}>+</button>
              </div>
            </div>
            <div className="a11y-slider">
              <span className="lbl">Espacement lettres</span>
              <span className="val">{(s.letterSpacing/100).toFixed(2)}em</span>
              <div className="stepper">
                <button onClick={() => upd('letterSpacing', Math.max(0, s.letterSpacing - 2))}>−</button>
                <button onClick={() => upd('letterSpacing', Math.min(20, s.letterSpacing + 2))}>+</button>
              </div>
            </div>
          </div>

          <div className="a11y-group">
            <div className="a11y-group-label">Contraste</div>
            <div className="a11y-opts">
              <button className={"a11y-opt" + (s.contrast==='normal' ? ' active' : '')} onClick={() => upd('contrast','normal')}>
                <span className="icon"><Icon name="sun" /></span>
                <span className="name">Normal</span>
                <span className="desc">Couleurs par défaut</span>
              </button>
              <button className={"a11y-opt" + (s.contrast==='dark' ? ' active' : '')} onClick={() => upd('contrast','dark')}>
                <span className="icon"><Icon name="moon" /></span>
                <span className="name">Sombre</span>
                <span className="desc">Fond sombre, repos des yeux</span>
              </button>
              <button className={"a11y-opt" + (s.contrast==='high' ? ' active' : '')} onClick={() => upd('contrast','high')}>
                <span className="icon"><Icon name="contrast" /></span>
                <span className="name">Très contrasté</span>
                <span className="desc">Noir & jaune WCAG AAA</span>
              </button>
            </div>
          </div>

          <div className="a11y-group">
            <div className="a11y-group-label">Vision des couleurs</div>
            <div className="a11y-opts">
              {[
                ['none', 'Aucun', 'Couleurs normales'],
                ['protanopia', 'Protanopie', 'Rouge'],
                ['deuteranopia', 'Deutéranopie', 'Vert'],
                ['tritanopia', 'Tritanopie', 'Bleu'],
                ['monochrome', 'Monochrome', 'Niveaux de gris'],
              ].map(([k, name, desc]) => (
                <button key={k} className={"a11y-opt" + (s.colorblind===k ? ' active' : '')} onClick={() => upd('colorblind', k)}>
                  <span className="icon"><Icon name="palette" /></span>
                  <span className="name">{name}</span>
                  <span className="desc">{desc}</span>
                </button>
              ))}
            </div>
          </div>

          <div className="a11y-group">
            <div className="a11y-group-label">Lecture</div>
            <div className="a11y-opts">
              <button className={"a11y-opt" + (s.dyslexia ? ' active' : '')} onClick={() => toggle('dyslexia')}>
                <span className="icon"><Icon name="type" /></span>
                <span className="name">Dyslexie</span>
                <span className="desc">Police + espacement adaptés</span>
              </button>
              <button className={"a11y-opt" + (s.links ? ' active' : '')} onClick={() => toggle('links')}>
                <span className="icon"><Icon name="link" /></span>
                <span className="name">Liens soulignés</span>
                <span className="desc">Tous les liens visibles</span>
              </button>
              <button className={"a11y-opt" + (s.guide ? ' active' : '')} onClick={() => toggle('guide')}>
                <span className="icon"><Icon name="read" /></span>
                <span className="name">Guide de lecture</span>
                <span className="desc">Barre qui suit la souris</span>
              </button>
              <button className={"a11y-opt" + (s.tts ? ' active' : '')} onClick={() => { upd('tts', !s.tts); ttsRead(); }}>
                <span className="icon"><Icon name="speaker" /></span>
                <span className="name">Lire la page</span>
                <span className="desc">Synthèse vocale</span>
              </button>
            </div>
          </div>

          <div className="a11y-group">
            <div className="a11y-group-label">Navigation</div>
            <div className="a11y-opts">
              <button className={"a11y-opt" + (s.motion==='reduce' ? ' active' : '')} onClick={() => upd('motion', s.motion==='reduce'?'normal':'reduce')}>
                <span className="icon"><Icon name="motion" /></span>
                <span className="name">Moins d'animations</span>
                <span className="desc">Réduit les mouvements</span>
              </button>
              <button className={"a11y-opt" + (s.cursor==='big' ? ' active' : '')} onClick={() => upd('cursor', s.cursor==='big'?'normal':'big')}>
                <span className="icon"><Icon name="cursor" /></span>
                <span className="name">Grand curseur</span>
                <span className="desc">Curseur agrandi et visible</span>
              </button>
            </div>
          </div>

          <button className="a11y-reset" onClick={reset}>Réinitialiser les préférences</button>
        </div>
      </div>
      <div className="reading-guide" id="reading-guide" />
      {/* SVG filters for colorblind modes */}
      <svg aria-hidden="true" style={{ position: 'absolute', width: 0, height: 0 }}>
        <defs>
          <filter id="cb-protanopia"><feColorMatrix values="0.567 0.433 0 0 0  0.558 0.442 0 0 0  0 0.242 0.758 0 0  0 0 0 1 0"/></filter>
          <filter id="cb-deuteranopia"><feColorMatrix values="0.625 0.375 0 0 0  0.7 0.3 0 0 0  0 0.3 0.7 0 0  0 0 0 1 0"/></filter>
          <filter id="cb-tritanopia"><feColorMatrix values="0.95 0.05 0 0 0  0 0.433 0.567 0 0  0 0.475 0.525 0 0  0 0 0 1 0"/></filter>
        </defs>
      </svg>
    </>
  );
}

Object.assign(window, { A11YWidget, Icon, useA11Y });
