/* Lecteur — couche d'annotation au stylet (pen / touch / souris) */

const PEN_COLORS = [
  { name: 'Encre',  value: '#05201e' },
  { name: 'Or',     value: '#fbb03b' },
  { name: 'Brique', value: '#a8453d' },
  { name: 'Bleu',   value: '#4a6b8a' },
  { name: 'Vert',   value: '#003333' },
];

const WIDTHS = {
  fin:    { pen: 3,  hi: 16 },
  normal: { pen: 5,  hi: 26 },
  epais:  { pen: 9,  hi: 42 },
};

const DEFAULT_DRAW_STATE = {
  active: false,
  tool: 'pen',          // 'pen' | 'highlighter' | 'eraser'
  color: '#05201e',
  width: 'normal',
};

function strokesOf(verse) { return verse?.strokes || []; }
function setStrokesOnVerse(lesson, vid, strokes) {
  return {
    ...lesson,
    verses: lesson.verses.map(v => v.id === vid ? { ...v, strokes } : v),
  };
}

function strokeNearPoint(s, p, r) {
  const r2 = r * r;
  for (const q of s.points) {
    const dx = q.x - p.x, dy = q.y - p.y;
    if (dx*dx + dy*dy < r2) return true;
  }
  return false;
}

function DrawingLayer({ active, strokes, onLive, onCommit, onRemove, author, tool, color, width }) {
  const svgRef = React.useRef(null);
  const [current, setCurrent] = React.useState(null);
  const [erasing, setErasing] = React.useState(false);
  const curRef  = React.useRef(null);   // trait en cours (source de vérité, anti-perte de points)
  const liveTs  = React.useRef(0);      // anti-flood pour la diffusion « en direct »

  const ptIn = (e) => {
    const svg = svgRef.current;
    if (!svg) return { x: 0, y: 0 };
    const r = svg.getBoundingClientRect();
    return {
      x: (e.clientX - r.left) / r.width * 1920,
      y: (e.clientY - r.top) / r.height * 1080,
    };
  };

  // Traits touchés par la gomme autour du point p
  const hitIds = (p) => strokes.filter(s => strokeNearPoint(s, p, 18)).map(s => s.id);

  const onDown = (e) => {
    if (!active) return;
    e.preventDefault();
    try { e.currentTarget.setPointerCapture(e.pointerId); } catch {}
    const p = ptIn(e);
    if (tool === 'eraser') {
      setErasing(true);
      const ids = hitIds(p);
      if (ids.length && onRemove) onRemove(ids);
      return;
    }
    const w = tool === 'highlighter' ? WIDTHS[width].hi : WIDTHS[width].pen;
    const c = tool === 'highlighter'
      ? hexWithAlpha(color === '#05201e' ? '#fbb03b' : color, 0.35)
      : color;
    const stroke = { id: uid(), author, ts: Date.now(), tool, color: c, width: w, points: [p] };
    curRef.current = stroke;
    setCurrent(stroke);
  };

  const onMove = (e) => {
    if (!active) return;
    const p = ptIn(e);
    if (erasing) {
      const ids = hitIds(p);
      if (ids.length && onRemove) onRemove(ids);
      return;
    }
    if (!curRef.current) return;
    const next = { ...curRef.current, points: [...curRef.current.points, p] };
    curRef.current = next;
    setCurrent(next);
    // Diffusion « en direct » du trait, limitée à ~60 ms pour ne pas saturer le réseau.
    const now = Date.now();
    if (onLive && next.points.length > 1 && now - liveTs.current > 60) {
      liveTs.current = now; onLive(next);
    }
  };

  const onUp = (e) => {
    if (erasing) { setErasing(false); return; }
    const cur = curRef.current;
    curRef.current = null;
    setCurrent(null);
    if (!cur) return;
    if (cur.points.length > 1) { if (onCommit) onCommit(cur); }
    else if (onRemove) { onRemove([cur.id]); }   // annule l'aperçu « en direct » chez les autres
  };

  return (
    <svg
      ref={svgRef}
      viewBox="0 0 1920 1080"
      preserveAspectRatio="none"
      style={{
        position:'absolute', inset:0, width:'100%', height:'100%',
        pointerEvents: active ? 'auto' : 'none',
        cursor: active ? (tool === 'eraser' ? 'cell' : 'crosshair') : 'default',
        zIndex: 30,
        touchAction: active ? 'none' : 'auto',
      }}
      onPointerDown={onDown}
      onPointerMove={onMove}
      onPointerUp={onUp}
      onPointerCancel={onUp}
      onPointerLeave={onUp}
    >
      {strokes.map(s => <StrokePath key={s.id} s={s}/>)}
      {current && <StrokePath s={current}/>}
    </svg>
  );
}

function StrokePath({ s }) {
  if (!s.points || s.points.length < 1) return null;
  if (s.points.length === 1) {
    const p = s.points[0];
    return <circle cx={p.x} cy={p.y} r={s.width / 2} fill={s.color}/>;
  }
  // Quadratic-smoothed path
  const pts = s.points;
  let d = `M${pts[0].x},${pts[0].y}`;
  for (let i = 1; i < pts.length - 1; i++) {
    const xc = (pts[i].x + pts[i+1].x) / 2;
    const yc = (pts[i].y + pts[i+1].y) / 2;
    d += ` Q${pts[i].x},${pts[i].y} ${xc},${yc}`;
  }
  const last = pts[pts.length - 1];
  d += ` L${last.x},${last.y}`;
  return (
    <path d={d} stroke={s.color} strokeWidth={s.width} fill="none"
      strokeLinecap="round" strokeLinejoin="round"/>
  );
}

function hexWithAlpha(hex, alpha) {
  if (!/^#[0-9a-f]{6}$/i.test(hex)) return hex;
  const a = Math.round(alpha * 255).toString(16).padStart(2, '0');
  return hex + a;
}

/* ---------- Floating toolbar over the stage ---------- */

function DrawingToolbar({ state, setState, strokes, onClearVerse, onUndo, onClose }) {
  const set = (patch) => setState(s => ({ ...s, ...patch }));
  const btn = (cond) => ({
    background: cond ? LBRAND.or : 'rgba(0, 36, 36, 0.85)',
    color: cond ? LBRAND.vert : '#fff',
    border: `1px solid ${cond ? LBRAND.or : 'rgba(251,176,59,0.4)'}`,
  });

  return (
    <div className="draw-toolbar">
      {/* Tool */}
      <div className="dt-group">
        <button onClick={() => set({ tool:'pen' })}
          style={btn(state.tool==='pen')}
          className="dt-btn" title="Stylet">
          ✎ Stylet
        </button>
        <button onClick={() => set({ tool:'highlighter' })}
          style={btn(state.tool==='highlighter')}
          className="dt-btn" title="Surligneur">
          ▌ Surligneur
        </button>
        <button onClick={() => set({ tool:'eraser' })}
          style={btn(state.tool==='eraser')}
          className="dt-btn" title="Gomme">
          ⌫ Gomme
        </button>
      </div>

      {/* Colors */}
      <div className="dt-group">
        {PEN_COLORS.map(c => (
          <button key={c.value}
            onClick={() => set({ color: c.value })}
            className={`dt-swatch ${state.color === c.value ? 'on' : ''}`}
            style={{ background: c.value }}
            title={c.name}/>
        ))}
      </div>

      {/* Width */}
      <div className="dt-group">
        {Object.keys(WIDTHS).map(k => (
          <button key={k}
            onClick={() => set({ width: k })}
            style={btn(state.width === k)}
            className="dt-btn dt-w" title={`Épaisseur ${k}`}>
            <span style={{
              display:'inline-block',
              width: WIDTHS[k].pen * 2,
              height: WIDTHS[k].pen * 2,
              background: state.width===k ? LBRAND.vert : '#fff',
              borderRadius: '50%',
            }}/>
          </button>
        ))}
      </div>

      {/* Actions */}
      <div className="dt-group">
        <button onClick={onUndo} className="dt-btn"
          style={btn(false)} title="Annuler (Ctrl+Z)" disabled={!strokes.length}>
          ↶ Annuler
        </button>
        <button onClick={onClearVerse} className="dt-btn"
          style={btn(false)} title="Effacer ce verset" disabled={!strokes.length}>
          ✕ Effacer
        </button>
      </div>

      <button onClick={onClose} className="dt-btn dt-close" title="Quitter le stylet">
        Quitter ✕
      </button>
    </div>
  );
}

Object.assign(window, {
  PEN_COLORS, WIDTHS, DEFAULT_DRAW_STATE,
  strokesOf, setStrokesOnVerse,
  DrawingLayer, StrokePath, DrawingToolbar,
});
