/* global React */
// ============================================================
// Guided tour engine — Navattic-style
// Renders a dim overlay with a spotlight cutout around a target
// element, plus a stepper tooltip (Back · "X of N" · Next).
// Modal steps render a centered card with no spotlight.
// ============================================================
const { useState: useTourState, useEffect: useTourEffect, useLayoutEffect, useRef: useTourRef, useCallback } = React;

function useRect(getEl, active, deps) {
  const [rect, setRect] = useTourState(null);
  useLayoutEffect(() => {
    if (!active) return;
    let raf;
    const measure = () => {
      const el = getEl();
      if (el) {
        const r = el.getBoundingClientRect();
        setRect({ top: r.top, left: r.left, width: r.width, height: r.height });
      } else {
        setRect(null);
      }
    };
    // measure now, then poll until the target mounts (handles view switches)
    measure();
    let tries = 0;
    const poll = () => {
      const el = getEl();
      const r = el && el.getBoundingClientRect();
      if (r && r.width > 0) { measure(); return; }
      if (tries++ < 40) raf = requestAnimationFrame(poll);
    };
    raf = requestAnimationFrame(poll);
    const onResize = () => measure();
    window.addEventListener('resize', onResize);
    const scroller = document.getElementById('app-scroll');
    if (scroller) scroller.addEventListener('scroll', onResize, true);
    return () => { cancelAnimationFrame(raf); window.removeEventListener('resize', onResize); if (scroller) scroller.removeEventListener('scroll', onResize, true); };
  }, deps);
  return rect;
}

function GuidedTour({ steps, index, onNext, onBack, onClose, getTarget }) {
  const step = steps[index];
  const isModal = step.modal;
  const total = steps.length;
  const rect = useRect(() => getTarget(step.target), !isModal && !!step.target, [index]);

  // ESC to close
  useTourEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      else if (e.key === 'ArrowRight' || e.key === 'Enter') onNext();
      else if (e.key === 'ArrowLeft') onBack();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [index]);

  const pad = step.pad != null ? step.pad : 8;
  const spot = rect ? { top: rect.top - pad, left: rect.left - pad, width: rect.width + pad * 2, height: rect.height + pad * 2 } : null;

  // ---- tooltip placement ----
  const TT_W = 320, GAP = 16;
  let ttStyle = {};
  let arrow = null;
  if (isModal || !spot) {
    ttStyle = { top: '50%', left: '50%', transform: 'translate(-50%,-50%)', width: 420 };
  } else {
    const place = step.placement || 'auto';
    const vw = window.innerWidth, vh = window.innerHeight;
    const spaceRight = vw - (spot.left + spot.width);
    const spaceLeft = spot.left;
    let p = place;
    if (place === 'auto') {
      if (spaceRight > TT_W + GAP + 20) p = 'right';
      else if (spaceLeft > TT_W + GAP + 20) p = 'left';
      else p = (spot.top + spot.height / 2 < vh / 2) ? 'bottom' : 'top';
    }
    if (p === 'right') {
      ttStyle = { top: Math.max(16, Math.min(spot.top + spot.height / 2, vh - 120)), left: spot.left + spot.width + GAP, transform: 'translateY(-50%)', width: TT_W };
      arrow = { left: -7, top: '50%', mt: -7, rot: 45, bl: true };
    } else if (p === 'left') {
      ttStyle = { top: Math.max(16, Math.min(spot.top + spot.height / 2, vh - 120)), left: Math.max(16, spot.left - GAP - TT_W), transform: 'translateY(-50%)', width: TT_W };
      arrow = { right: -7, top: '50%', mt: -7, rot: 45, br: true };
    } else if (p === 'bottom') {
      ttStyle = { top: spot.top + spot.height + GAP, left: clampX(spot.left + spot.width / 2 - TT_W / 2, vw, TT_W), width: TT_W };
      arrow = { top: -7, left: spot.left + spot.width / 2 - clampX(spot.left + spot.width / 2 - TT_W / 2, vw, TT_W) - 7, rot: 45, tl: true };
    } else { // top
      ttStyle = { top: spot.top - GAP - 150, left: clampX(spot.left + spot.width / 2 - TT_W / 2, vw, TT_W), width: TT_W };
      arrow = { bottom: -7, left: spot.left + spot.width / 2 - clampX(spot.left + spot.width / 2 - TT_W / 2, vw, TT_W) - 7, rot: 45, br2: true };
    }
  }

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 1000 }}>
      {/* dim + spotlight */}
      {isModal || !spot ? (
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(15,44,77,0.55)' }} onClick={onClose} />
      ) : (
        <>
          {/* four scrim panels framing the spotlight hole (reliable across renderers) */}
          {[
            { top: 0, left: 0, right: 0, height: spot.top },
            { top: spot.top + spot.height, left: 0, right: 0, bottom: 0 },
            { top: spot.top, left: 0, width: spot.left, height: spot.height },
            { top: spot.top, left: spot.left + spot.width, right: 0, height: spot.height },
          ].map((p, i) => (
            <div key={i} onClick={onClose} style={{ position: 'absolute', background: 'rgba(15,44,77,0.55)', transition: 'all .35s cubic-bezier(.4,0,.2,1)', ...p }} />
          ))}
          {/* highlight ring */}
          <div style={{
            position: 'absolute', top: spot.top, left: spot.left, width: spot.width, height: spot.height,
            borderRadius: step.spotRadius != null ? step.spotRadius : 14,
            border: '2px solid #3CB4A4', boxShadow: '0 0 0 4px rgba(60,180,164,0.25)',
            transition: 'all .35s cubic-bezier(.4,0,.2,1)', pointerEvents: 'none',
          }} />
        </>
      )}

      {/* tooltip / modal card */}
      <div style={{ position: 'absolute', ...ttStyle, transition: isModal ? 'none' : 'all .35s cubic-bezier(.4,0,.2,1)' }}>
        <div style={{ position: 'relative', background: '#fff', borderRadius: 16, boxShadow: '0 24px 60px -16px rgba(15,44,77,0.45)', padding: isModal ? '36px 36px 24px' : '22px 22px 16px' }}>
          {arrow && <Arrow a={arrow} />}
          {isModal && step.eyebrow && (
            <div style={{ fontFamily: 'ui-monospace, monospace', fontSize: 12, letterSpacing: '.14em', color: '#3CB4A4', fontWeight: 700, marginBottom: 12, textAlign: 'center' }}>{step.eyebrow}</div>
          )}
          {step.title && (
            <div style={{ fontFamily: 'Georgia, serif', fontWeight: 800, color: '#0F2C4D', fontSize: isModal ? 30 : 18, lineHeight: 1.15, marginBottom: 10, textAlign: isModal ? 'center' : 'left' }}>{step.title}</div>
          )}
          <div style={{ color: '#5b6b80', fontSize: isModal ? 16 : 14, lineHeight: 1.55, textAlign: isModal ? 'center' : 'left' }}>{step.body}</div>

          {/* controls */}
          <div style={{ display: 'flex', alignItems: 'center', marginTop: isModal ? 26 : 18 }}>
            {index > 0 ? (
              <button onClick={onBack} style={btn.back}>Back</button>
            ) : <span style={{ width: 1 }} />}
            <div style={{ flex: 1, textAlign: 'center', fontSize: 12.5, color: '#aab3c2', fontWeight: 600 }}>{index + 1} of {total}</div>
            <button onClick={onNext} style={btn.next}>{index === total - 1 ? (step.finalLabel || 'Finish') : 'Next'}</button>
          </div>

          {isModal && <div style={{ textAlign: 'center', fontSize: 11, color: '#c2cad6', marginTop: 16 }}>Pelcro Product Tour</div>}
        </div>
      </div>

      {/* close */}
      <button onClick={onClose} aria-label="Close tour" style={{
        position: 'fixed', top: 16, right: 16, width: 36, height: 36, borderRadius: 18, border: 'none',
        background: '#fff', color: '#5b6b80', fontSize: 18, cursor: 'pointer', boxShadow: '0 4px 12px rgba(15,44,77,0.18)', zIndex: 1002,
      }}>×</button>
    </div>
  );
}

function Arrow({ a }) {
  const st = {
    position: 'absolute', width: 14, height: 14, background: '#fff',
    transform: `rotate(${a.rot}deg)`,
  };
  if (a.left != null) st.left = a.left;
  if (a.right != null) st.right = a.right;
  if (a.top != null) st.top = a.top;
  if (a.bottom != null) st.bottom = a.bottom;
  if (a.mt != null) st.marginTop = a.mt;
  return <div style={st} />;
}

function clampX(x, vw, w) { return Math.max(16, Math.min(x, vw - w - 16)); }

// Floating restart pill
function TourPill({ onClick }) {
  return (
    <button onClick={onClick} style={{
      position: 'fixed', bottom: 22, right: 22, zIndex: 900,
      background: '#0F2C4D', color: '#fff', border: 'none', borderRadius: 12,
      padding: '12px 20px', fontWeight: 700, fontSize: 14, cursor: 'pointer',
      boxShadow: '0 12px 30px -10px rgba(15,44,77,0.5)', display: 'flex', alignItems: 'center', gap: 8,
    }}>
      <span style={{ width: 8, height: 8, borderRadius: 4, background: '#3CB4A4' }} />
      Product Tour
    </button>
  );
}

const btn = {
  back: { background: '#fff', color: '#0F2C4D', border: '1.5px solid #e6ebf0', borderRadius: 9, padding: '9px 18px', fontWeight: 700, fontSize: 13, cursor: 'pointer' },
  next: { background: '#0F2C4D', color: '#fff', border: 'none', borderRadius: 9, padding: '10px 22px', fontWeight: 700, fontSize: 13, cursor: 'pointer' },
};

Object.assign(window, { GuidedTour, TourPill });
