/** @jsx React.createElement */
/* GuidedTour: spotlight walkthrough overlaid on the live dashboard.
   Non-blocking: the page stays fully interactive while the tour runs. */

const APO_TOUR_KEY = 'apoTourDone.v1';

function apoTourSteps(setView) {
  const q = (sel) => document.querySelector(sel);
  return [
    { title: 'Welcome to your Active Projects Overview', body: 'This is the live version of the weekly PowerPoint chart. Everything you see is real data, and everything is editable. This short tour shows you around; you can click and try things at any point.', target: null },
    { title: 'The board', body: 'Rows are therapeutic areas, columns are assessment stages. Each card is one opportunity: organization on top, asset below. Counts along the bottom update as things move.', view: 'chart', target: () => q('[data-tour="matrix"]'), pad: 6 },
    { title: 'Drag cards between stages', body: 'Move an opportunity forward (or back) by dragging its card to another stage column. Go ahead and try dragging this one. Click a card to open and edit its details.', view: 'chart', target: () => q('.apo-chip'), pad: 8 },
    { title: 'Status this week', body: 'Colored markers on a card show what changed: new this week, priority, under monitoring, deprioritized, terminated. Auralis Onc\u2019s AUR-509 is currently flagged \u201cunder monitoring vs last week\u201d.', view: 'chart', target: () => { const chips = [...document.querySelectorAll('.apo-chip')]; return chips.find(c => c.textContent.includes('AUR-509')) || chips[0]; }, pad: 8 },
    { title: 'Filter with the legend', body: 'Hover a legend item to highlight matching opportunities; click it to hide them (click again to bring them back). Combine as many as you like. Filters apply in both Chart and Table view.', target: () => q('[data-tour="legend"]'), pad: 6 },
    { title: 'Two views, same data', body: 'Switch between the chart and a detailed table whenever you like. Edits made in one view show up in the other instantly.', view: 'table', target: () => q('[data-tour="seg"]'), pad: 6 },
    { title: 'Filter by stage', body: 'These tabs filter the table. Click several to combine stages; \u201cAll\u201d resets. You can also land here pre-filtered by clicking a stage header or count on the chart.', view: 'table', target: () => q('[data-tour="tabs"]'), pad: 6 },
    { title: 'Edit anything inline', body: 'Click any cell to edit it in place: company, asset, BD lead, next step\u2026 Drag the edge of a column header to resize it.', view: 'table', target: () => q('.apot thead'), pad: 4 },
    { title: 'Add new opportunities', body: 'Click \u201cNew opportunity\u201d to add one, then pick the organization and asset from the list or type a new name. It lands on the board immediately.', target: () => q('[data-tour="new"]'), pad: 6 },
    { title: 'Export and share', body: 'The \u22ee menu exports the current view to PowerPoint, PDF, Excel or an image, handy for the weekly readout. That\u2019s the tour. Explore freely. Replay it anytime with the \u201cTour\u201d button up top.', target: () => q('.apo-menu') || q('[data-tour="menu"]'), pad: 6, onEnter: () => { const b = q('[data-tour="menu"]'); if (b && b.dataset.on !== 'true') b.click(); }, onLeave: () => { const b = q('[data-tour="menu"]'); if (b && b.dataset.on === 'true') b.click(); } },
  ];
}

function GuidedTour({ setView }) {
  const [step, setStep] = React.useState(() => { try { return localStorage.getItem(APO_TOUR_KEY) ? -1 : 0; } catch (e) { return 0; } });
  const [rect, setRect] = React.useState(null);
  const steps = React.useMemo(() => apoTourSteps(setView), [setView]);
  const open = step >= 0 && step < steps.length;
  const cur = open ? steps[step] : null;

  const finish = React.useCallback(() => { setStep(-1); setView('chart'); try { localStorage.setItem(APO_TOUR_KEY, '1'); } catch (e) {} }, [setView]);
  const start = React.useCallback(() => setStep(0), []);
  React.useEffect(() => { window.__apoTourStart = start; return () => { delete window.__apoTourStart; }; }, [start]);

  // Switch view when a step needs it; run enter/leave hooks
  React.useEffect(() => {
    if (cur && cur.view) setView(cur.view);
    if (cur && cur.onEnter) setTimeout(cur.onEnter, 50);
    return () => { if (cur && cur.onLeave) cur.onLeave(); };
  }, [step]);

  // Track the target's rect (poll: layout shifts, view switches, drags)
  React.useEffect(() => {
    if (!open) { setRect(null); return; }
    let raf;
    const scrolled = { current: false };
    const measure = () => {
      const el = cur.target ? cur.target() : null;
      if (!el) { setRect(null); return; }
      const z = document.documentElement.currentCSSZoom || 1;
      const b = el.getBoundingClientRect();
      let r = { top: b.top / z, bottom: b.bottom / z, left: b.left / z, width: b.width / z, height: b.height / z };
      if (r.width === 0 && r.height === 0) { setRect(null); return; }
      // keep target visible: scroll the pane ONCE per step (re-scrolling every
      // poll oscillates when the target is taller than the pane)
      const pane = document.querySelector('.content');
      if (pane && !scrolled.current) {
        scrolled.current = true;
        const pb = pane.getBoundingClientRect();
        const pr = { top: pb.top / z, bottom: pb.bottom / z, height: pb.height / z };
        if (r.height >= pr.height - 20 || r.top < pr.top + 10) pane.scrollTop += r.top - pr.top - 60;
        else if (r.bottom > pr.bottom - 10) pane.scrollTop += r.bottom - pr.bottom + 60;
        const b2 = el.getBoundingClientRect();
        r = { top: b2.top / z, bottom: b2.bottom / z, left: b2.left / z, width: b2.width / z, height: b2.height / z };
      }
      const p = cur.pad || 0;
      setRect({ top: r.top - p, left: r.left - p, width: r.width + p * 2, height: r.height + p * 2 });
    };
    measure();
    const iv = setInterval(() => { raf = requestAnimationFrame(measure); }, 350);
    window.addEventListener('resize', measure);
    return () => { clearInterval(iv); cancelAnimationFrame(raf); window.removeEventListener('resize', measure); };
  }, [step, open]);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') finish();
      else if (e.key === 'ArrowRight') setStep(s => Math.min(s + 1, steps.length - 1));
      else if (e.key === 'ArrowLeft') setStep(s => Math.max(s - 1, 0));
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, finish, steps.length]);

  if (!open) return null;
  const last = step === steps.length - 1;

  // Tooltip placement: below target if room, else above; centered if no target
  const card = { w: 336 };
  let cardStyle;
  if (rect) {
    const zz = document.documentElement.currentCSSZoom || 1;
    const vw = window.innerWidth / zz, vh = window.innerHeight / zz;
    const below = rect.top + rect.height + 16;
    const fitsBelow = below + 230 < vh;
    const top = fitsBelow ? below : Math.max(16, rect.top - 16 - 224);
    const left = Math.max(16, Math.min(rect.left + rect.width / 2 - card.w / 2, vw - card.w - 16));
    cardStyle = { top, left };
  } else {
    cardStyle = { top: '50%', left: '50%', transform: 'translate(-50%,-50%)' };
  }

  return (
    <React.Fragment>
      {rect ? (
        <div className="tour-spot" style={{ top: rect.top, left: rect.left, width: rect.width, height: rect.height }}></div>
      ) : (
        <div className="tour-dim"></div>
      )}
      <div className="tour-card" style={cardStyle} role="dialog" aria-label="Guided tour">
        <div className="tour-step-num">Step {step + 1} of {steps.length}</div>
        <h3 className="tour-title">{cur.title}</h3>
        <p className="tour-body">{cur.body}</p>
        <div className="tour-foot">
          <div className="tour-dots">{steps.map((s, i) => <span key={i} data-on={i === step} onClick={() => setStep(i)}></span>)}</div>
          <div className="tour-btns">
            <button className="tour-skip" onClick={finish}>{last ? '' : 'Skip'}</button>
            {step > 0 && <button className="tour-back" onClick={() => setStep(step - 1)}>Back</button>}
            <button className="tour-next" onClick={() => (last ? finish() : setStep(step + 1))}>{last ? 'Done' : 'Next'}</button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

function TourLaunchButton() {
  return (
    <button className="apo-ghostbtn" title="Replay the guided tour" onClick={() => window.__apoTourStart && window.__apoTourStart()}>
      <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M10 8.5l5 3.5-5 3.5z"/></svg>
      Tour
    </button>
  );
}

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