// CursorBubble — follows cursor, shows only inside tracked sections, auto-hides

const MESSAGES = [
  { id: "ag-section-home",     key: "home"     },
  { id: "ag-section-services", key: "services" },
  { id: "ag-section-about",    key: "about"    },
  { id: "ag-section-reviews",  key: "reviews"  },
  { id: "ag-section-how",      key: "how"      },
  { id: "ag-section-works",    key: "works"    },
  { id: "ag-section-pricing",  key: "pricing"  },
  { id: "ag-section-faq",      key: "faq"      },
  { id: "ag-section-contact",  key: "contact"  },
];

// Reads lang from <html lang="..."> set by app.jsx
const getBubbleLang = () => {
  const l = document.documentElement.lang;
  return l === 'ar-MA' ? 'dar' : (l || 'en');
};

const HIDE_AFTER_MS = 3500; // auto-hide 3.5s after typing completes

const CursorBubble = () => {
  const outerRef       = React.useRef(null);
  const rafRef         = React.useRef(null);
  const typingRef      = React.useRef(null);
  const hideTimerRef   = React.useRef(null);
  const pos            = React.useRef({ tx: 0, ty: 0, cx: 0, cy: 0, init: false });
  const currentMsg     = React.useRef('');
  const lastSectionRef = React.useRef(null);

  const [visible,     setVisible]     = React.useState(false);
  const [targetText,  setTargetText]  = React.useState('');
  const [displayText, setDisplayText] = React.useState('');

  // ── lerp follow loop — always runs regardless of visibility ──
  React.useEffect(() => {
    const tick = () => {
      const p = pos.current;
      p.cx += (p.tx - p.cx) * 0.13;
      p.cy += (p.ty - p.cy) * 0.13;
      if (outerRef.current) {
        outerRef.current.style.transform = `translate(${p.cx}px,${p.cy}px)`;
      }
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, []);

  // ── cursor tracking + section enter/leave detection ──────────
  React.useEffect(() => {
    const onMove = (e) => {
      pos.current.tx = e.clientX + 20;
      pos.current.ty = e.clientY - 64;
      if (!pos.current.init) {
        pos.current.cx = pos.current.tx;
        pos.current.cy = pos.current.ty;
        pos.current.init = true;
      }

      const mx = e.clientX, my = e.clientY;
      let found = null;
      for (const m of MESSAGES) {
        const el = document.getElementById(m.id);
        if (!el) continue;
        const rect = el.getBoundingClientRect();
        if (mx >= rect.left && mx <= rect.right && my >= rect.top && my <= rect.bottom) {
          found = m;
          break;
        }
      }

      if (found) {
        if (found.id !== lastSectionRef.current) {
          // Entered a new section — show bubble with new message
          lastSectionRef.current = found.id;
          clearTimeout(hideTimerRef.current);
          setVisible(true);
          const msg = t('cursorBubble.' + found.key, getBubbleLang());
          if (msg !== currentMsg.current) {
            currentMsg.current = msg;
            setTargetText(msg);
          }
        }
        // Same section: let the auto-hide timer run after typing completes
      } else {
        // Left all tracked sections — hide immediately
        if (lastSectionRef.current !== null) {
          lastSectionRef.current = null;
          clearTimeout(hideTimerRef.current);
          setVisible(false);
        }
      }
    };

    window.addEventListener('mousemove', onMove, { passive: true });
    return () => window.removeEventListener('mousemove', onMove);
  }, []);

  // ── typing effect — auto-hide after completion ────────────────
  React.useEffect(() => {
    if (!targetText) return;
    clearInterval(typingRef.current);
    clearTimeout(hideTimerRef.current);
    setDisplayText('');
    const chars = [...targetText];
    let i = 0;
    const delay = setTimeout(() => {
      typingRef.current = setInterval(() => {
        i++;
        setDisplayText(chars.slice(0, i).join(''));
        if (i >= chars.length) {
          clearInterval(typingRef.current);
          // Auto-hide after message has been fully read
          hideTimerRef.current = setTimeout(() => setVisible(false), HIDE_AFTER_MS);
        }
      }, 36);
    }, 120);
    return () => { clearTimeout(delay); clearInterval(typingRef.current); };
  }, [targetText]);

  // Hide on touch/coarse-pointer devices (no cursor present)
  if ('ontouchstart' in window || window.matchMedia?.('(pointer: coarse)').matches) return null;

  return (
    <div ref={outerRef} className="ag-cursor-bubble" aria-hidden="true">
      <div className={'ag-cursor-bubble__body' + (visible ? ' is-visible' : '')}>
        <span className="ag-cursor-bubble__text">{displayText}</span>
        <span className="ag-cursor-bubble__caret" />
      </div>
    </div>
  );
};

window.CursorBubble = CursorBubble;
