// Guided tours, help icons, help modal — institutional, non-playful
// No gamification, no colored icons. Matches Epic/Cerner/NHS feel.

// ---------------- HelpIcon ----------------
function HelpIcon({ text, title, label }) {
  const [open, setOpen] = React.useState(false);
  const aria = label || title || 'More information';
  return (
    <span
      className="help-icon"
      tabIndex={0}
      role="button"
      aria-label={aria}
      aria-describedby={open ? undefined : undefined}
      onMouseEnter={() => setOpen(true)}
      onMouseLeave={() => setOpen(false)}
      onFocus={() => setOpen(true)}
      onBlur={() => setOpen(false)}
      onKeyDown={(e) => { if (e.key === 'Escape') setOpen(false); }}
    >
      i
      {open && (
        <span className="help-tip" role="tooltip">
          {title && <><strong>{title}</strong><br/></>}
          {text}
        </span>
      )}
    </span>
  );
}

// ---------------- TakeTourButton ----------------
function TakeTourButton({ onClick }) {
  return (
    <button className="tour-btn" onClick={onClick} aria-label="Take a guided tour of this page">
      <I.HelpCircle size={13}/>
      Take a tour
    </button>
  );
}

// ---------------- Phase2Badge ----------------
// Reused anywhere the UI reserves an anchor for a future LLM-assisted feature.
// The brief (§7) requires the AI orchestration boundary to be visible from
// day one without letting AI own the critical path in v1.
function Phase2Badge() {
  return (
    <span className="phase2-badge" title="Reserved for Phase 2 · LLM-assisted feature">
      <I.Lock size={9}/> Phase 2
    </span>
  );
}

// ---------------- Tour definitions ----------------
const TOURS = {
  learner: [
    {
      selector: '[data-tour="learner-training"]',
      title: 'Your training',
      body: "This is where you'll find all courses assigned to you by the compliance team. Overdue items appear at the top."
    },
    {
      selector: '[data-tour="learner-kpis"]',
      title: 'Quick status summary',
      body: "A summary of your training status. 'Compliance status: Current' means you have no overdue items."
    },
    {
      selector: '[data-tour="learner-list"]',
      title: 'Open a lesson',
      body: "Click 'Continue' or 'Start' to open a lesson. You can leave at any time — your progress is saved automatically."
    },
    {
      selector: '[data-tour="learner-simulations"]',
      title: 'Simulated phishing',
      body: "From time to time the security team sends simulated phishing emails. If you spot one, report it from here. These tests are never graded punitively."
    },
    {
      selector: '[data-tour="learner-incident"]',
      title: 'Reporting an incident',
      body: "If you see something suspicious — a strange email, a lost device, a privacy concern — report it here. You never need to include patient names."
    },
    {
      selector: '[data-tour="tour-button"]',
      title: 'Replay this tour anytime',
      body: "You can replay this tour anytime from this button. If you get stuck, contact IT at ext. 4400."
    },
  ],
  manager: [
    {
      selector: '[data-tour="manager-kpis"]',
      title: 'Department metrics',
      body: "Department-wide metrics for your compliance period. Trend arrows compare to the previous month."
    },
    {
      selector: '[data-tour="manager-dept"]',
      title: 'Completion by department',
      body: "Identify which departments are falling behind on mandatory training."
    },
    {
      selector: '[data-tour="manager-phish"]',
      title: 'Phishing results',
      body: "Tracks click-rate across the last 6 simulation campaigns. Lower is better."
    },
    {
      selector: '[data-tour="manager-followup"]',
      title: 'Staff needing follow-up',
      body: "Click 'Send reminder' to trigger an automated email. All reminders are logged for audit."
    },
    {
      selector: '[data-tour="manager-export"]',
      title: 'Audit-ready export',
      body: "Export a PDF or CSV of this dashboard for HIPAA/NIST audit evidence."
    },
  ],
  admin: [
    {
      selector: '[data-tour="admin-tabs"]',
      title: 'Content types',
      body: "All learning content lives here, grouped by type."
    },
    {
      selector: '[data-tour="admin-status"]',
      title: 'Content lifecycle',
      body: "Content moves through Draft → Review → Approved → Published. Only Published items are visible to learners."
    },
    {
      selector: '[data-tour="admin-version"]',
      title: 'Version history',
      body: "Every edit increments the version. Previous versions remain viewable for audit."
    },
    {
      selector: '[data-tour="admin-new"]',
      title: 'Create new content',
      body: "Start a new item in Draft. It won't reach learners until it's Approved and Published."
    },
  ],
};

// ---------------- Tour component ----------------
function Tour({ role, open, onClose }) {
  const rawSteps = TOURS[role] || [];
  const [idx, setIdx] = React.useState(0);
  const [rect, setRect] = React.useState(null);
  const [isMobile, setIsMobile] = React.useState(() => typeof window !== 'undefined' && window.innerWidth <= 768);

  React.useEffect(() => {
    const onResize = () => setIsMobile(window.innerWidth <= 768);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  // On mobile the sidebar lives behind a hamburger drawer, so steps that
  // spotlight sidebar items can't be reached. Filter those out so mobile
  // tours stay on the main content only.
  const sidebarSelectors = ['learner-training', 'learner-simulations', 'learner-incident'];
  const steps = isMobile
    ? rawSteps.filter(s => !sidebarSelectors.some(k => s.selector.includes(k)))
    : rawSteps;

  // Always reset to step 0 when the role changes or the tour re-opens.
  // Without this, switching roles (e.g. learner → admin) keeps the old idx
  // and produces bogus "Step 13 of 4" states.
  React.useEffect(() => {
    setIdx(0);
    setRect(null);
  }, [role, open, isMobile]);

  // Guard against out-of-range idx if steps length shrinks.
  const safeIdx = Math.min(idx, Math.max(steps.length - 1, 0));

  // Compute spotlight + card position
  const compute = React.useCallback(() => {
    const step = steps[safeIdx];
    if (!step) return;
    const el = document.querySelector(step.selector);
    if (!el) { setRect(null); return; }
    const r = el.getBoundingClientRect();
    setRect({
      top: r.top - 6, left: r.left - 6,
      width: r.width + 12, height: r.height + 12,
      cx: r.left + r.width / 2, cy: r.top + r.height / 2,
      bottom: r.bottom, right: r.right,
    });
    // scroll into view gently
    const vh = window.innerHeight;
    if (r.top < 80 || r.bottom > vh - 80) {
      window.scrollTo({ top: window.scrollY + r.top - vh / 3, behavior: 'smooth' });
    }
  }, [safeIdx, steps]);

  React.useEffect(() => {
    if (!open) return;
    // wait a frame to ensure anchors are rendered
    const t = setTimeout(compute, 30);
    window.addEventListener('resize', compute);
    window.addEventListener('scroll', compute, true);
    return () => {
      clearTimeout(t);
      window.removeEventListener('resize', compute);
      window.removeEventListener('scroll', compute, true);
    };
  }, [open, safeIdx, compute]);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') { e.preventDefault(); onClose(); }
      else if (e.key === 'ArrowRight' || e.key === 'Enter') { e.preventDefault(); next(); }
      else if (e.key === 'ArrowLeft') { e.preventDefault(); prev(); }
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  });

  if (!open) return null;

  const last = safeIdx >= steps.length - 1;
  const next = () => { if (last) onClose(); else setIdx(safeIdx + 1); };
  const prev = () => { if (safeIdx > 0) setIdx(safeIdx - 1); };

  // Card placement. Pick the side of the spotlight that gives the card room
  // without sitting on top of it or disappearing off-screen.
  //
  // Rules:
  //   - Anchor in the left sidebar  → prefer RIGHT of spotlight.
  //   - Anchor wide (spans main)    → prefer BELOW, else ABOVE.
  //   - Anchor narrow near the right edge → prefer LEFT.
  //   - Fall back to whichever side fits; final clamp keeps it on-screen.
  let cardStyle = { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' };
  if (rect) {
    const vw = window.innerWidth, vh = window.innerHeight;
    const cardW = 340, cardH = 210;
    const margin = 14, edge = 16;
    const sidebarW = 220;
    const fitsBelow = rect.bottom + margin + cardH <= vh - edge;
    const fitsAbove = rect.top - margin - cardH >= edge;
    const fitsRight = rect.right + margin + cardW <= vw - edge;
    const fitsLeft  = rect.left - margin - cardW >= edge;
    const inSidebar = rect.right <= sidebarW + 8;
    const nearRightEdge = rect.left > vw - sidebarW;

    const placements = [];
    if (inSidebar) placements.push('right', 'below', 'above', 'left');
    else if (nearRightEdge) placements.push('left', 'below', 'above', 'right');
    else placements.push('below', 'above', 'right', 'left');

    const fits = { below: fitsBelow, above: fitsAbove, right: fitsRight, left: fitsLeft };
    const side = placements.find(p => fits[p]) || placements[0];

    let top, left;
    if (side === 'below') {
      top = rect.bottom + margin;
      left = rect.left + rect.width / 2 - cardW / 2;
    } else if (side === 'above') {
      top = rect.top - margin - cardH;
      left = rect.left + rect.width / 2 - cardW / 2;
    } else if (side === 'right') {
      left = rect.right + margin;
      top = rect.top;
    } else {
      left = rect.left - margin - cardW;
      top = rect.top;
    }
    // Final clamp to viewport edges.
    left = Math.max(edge, Math.min(left, vw - cardW - edge));
    top  = Math.max(edge, Math.min(top,  vh - cardH - edge));
    cardStyle = { top: `${top}px`, left: `${left}px` };
  }

  const step = steps[safeIdx];
  if (!step) return null;

  return (
    <div className="tour-overlay" role="dialog" aria-modal="true" aria-label={`Tour step ${safeIdx + 1} of ${steps.length}`}>
      <div className="tour-mask" onClick={onClose}/>
      {rect && (
        <div
          className="tour-spotlight"
          style={{ top: rect.top, left: rect.left, width: rect.width, height: rect.height }}
        />
      )}
      <div className="tour-card" style={cardStyle} onClick={e => e.stopPropagation()}>
        <div className="tour-card-head">
          <span className="tour-step">Step {safeIdx + 1} of {steps.length}</span>
          <button className="tour-card-close" aria-label="Close tour" onClick={onClose}>
            <I.XCircle size={16}/>
          </button>
        </div>
        <div className="tour-card-body">
          <h3>{step.title}</h3>
          <p>{step.body}</p>
        </div>
        <div className="tour-dots" aria-hidden="true">
          {steps.map((_, i) => (
            <span key={i} className={i === safeIdx ? 'active' : i < safeIdx ? 'done' : ''}/>
          ))}
        </div>
        <div className="tour-card-foot">
          <button className="tour-skip" onClick={onClose}>Skip tour</button>
          <div className="tour-nav">
            <button className="btn btn-sm btn-outline" onClick={prev} disabled={safeIdx === 0}>Back</button>
            <button className="btn btn-sm btn-primary" onClick={next} autoFocus>
              {last ? 'Finish' : 'Next'}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---------------- Tour controller hook ----------------
// Returns { open, start, close, TourEl } — handles first-run autoplay per role.
function useTour(role) {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    if (!role) return;
    const key = `medishield_tour_${role}_seen`;
    try {
      if (!localStorage.getItem(key)) {
        // short delay so the page has mounted & anchors are there
        const t = setTimeout(() => setOpen(true), 500);
        return () => clearTimeout(t);
      }
    } catch (e) {}
  }, [role]);

  const start = React.useCallback(() => setOpen(true), []);
  const close = React.useCallback(() => {
    setOpen(false);
    try { localStorage.setItem(`medishield_tour_${role}_seen`, '1'); } catch (e) {}
  }, [role]);

  return { open, start, close };
}

// ---------------- HelpModal ----------------
function HelpModal({ open, onClose, onReplayTour, toast }) {
  if (!open) return null;
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{maxWidth: 480}}>
        <div style={{padding: '18px 22px', borderBottom: '1px solid var(--border-2)', display: 'flex', alignItems: 'center', justifyContent: 'space-between'}}>
          <div>
            <h2 style={{margin: 0}}>Help & support</h2>
            <p className="muted" style={{fontSize: 12.5, marginTop: 4}}>Find your way around MediShield.</p>
          </div>
          <button className="icon-btn" aria-label="Close" onClick={onClose}><I.XCircle size={16}/></button>
        </div>
        <div style={{padding: 8}}>
          <button
            className="side-item"
            style={{padding: '12px 14px', borderLeft: 'none'}}
            onClick={() => { onClose(); onReplayTour(); }}
          >
            <I.Compass size={15} color="var(--navy)"/>
            <div style={{textAlign: 'left'}}>
              <div style={{fontWeight: 600, color: 'var(--navy)', fontSize: 13}}>Take the tour again</div>
              <div style={{fontSize: 12, color: 'var(--ink-3)', fontWeight: 400}}>Re-launch the guided walkthrough for this dashboard.</div>
            </div>
          </button>

          <div style={{padding: '10px 14px', borderTop: '1px solid var(--border-2)', marginTop: 4}}>
            <div style={{display: 'flex', gap: 10, alignItems: 'flex-start'}}>
              <I.Keyboard size={15} color="var(--navy)" style={{marginTop: 2, flexShrink: 0}}/>
              <div style={{flex: 1}}>
                <div style={{fontWeight: 600, color: 'var(--navy)', fontSize: 13, marginBottom: 6}}>Keyboard shortcuts</div>
                <div style={{display: 'grid', gridTemplateColumns: '1fr auto', gap: '4px 16px', fontSize: 12.5, color: 'var(--ink-2)'}}>
                  <span>Search anywhere</span>
                  <span className="mono" style={{color: 'var(--ink-3)'}}>⌘ K</span>
                  <span>Close dialog or tour</span>
                  <span className="mono" style={{color: 'var(--ink-3)'}}>Esc</span>
                  <span>Move through fields</span>
                  <span className="mono" style={{color: 'var(--ink-3)'}}>Tab</span>
                  <span>Next / previous tour step</span>
                  <span className="mono" style={{color: 'var(--ink-3)'}}>← / →</span>
                </div>
              </div>
            </div>
          </div>

          <div style={{padding: '10px 14px', borderTop: '1px solid var(--border-2)'}}>
            <div style={{display: 'flex', gap: 10, alignItems: 'flex-start'}}>
              <I.Phone size={15} color="var(--navy)" style={{marginTop: 2, flexShrink: 0}}/>
              <div>
                <div style={{fontWeight: 600, color: 'var(--navy)', fontSize: 13}}>Contact IT support</div>
                <div style={{fontSize: 12.5, color: 'var(--ink-2)'}}>
                  Call extension <span className="mono" style={{fontWeight: 600, color: 'var(--navy)'}}>4400</span> from any hospital phone, or email <span className="mono">it-help@stlukes.org</span>.
                </div>
              </div>
            </div>
          </div>

          <div style={{padding: '10px 14px', borderTop: '1px solid var(--border-2)'}}>
            <button
              className="btn btn-outline btn-sm"
              style={{width: '100%', justifyContent: 'flex-start'}}
              onClick={() => { onClose(); toast('Thanks — logged for the IT team.', 'success'); }}
            >
              <I.Bug size={13}/> Report a bug
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { HelpIcon, TakeTourButton, Phase2Badge, Tour, useTour, HelpModal, TOURS });
