/* Guided product tour for tenants.
 *
 * A spotlight walkthrough of the most critical features. It anchors a coach
 * card to the real sidebar nav items (via [data-tour="<route>"] added in
 * shared.jsx) and navigates the app to each page as it goes, so tenants see
 * the actual screen behind the highlight.
 *
 * Launch:
 *   - Auto-starts once for a tenant the first time they reach the dashboard
 *     (gated by localStorage TOUR_SEEN_KEY).
 *   - Re-launchable anytime via the "Take a tour" menu items, which dispatch
 *     a window "mk-start-tour" event.
 *
 * Self-contained: exported to window.TenantTour and rendered from root.jsx.
 */
const { useState, useEffect, useRef, useCallback } = React;

const TOUR_SEEN_KEY = "mk-tour-tenant-v1";

/* Each step either spotlights a sidebar nav item (route = nav id, also the
   page we navigate to) or renders centered (route = null). */
const TENANT_TOUR_STEPS = [
  {
    key: "welcome",
    route: null,
    icon: "sparkles",
    title: "Welcome to Mikaka",
    body: "Mikaka answers your phone calls, understands what each caller wants, and turns every conversation into intelligence and action. Here's a 60-second tour of the essentials.",
    next: "Show me around",
  },
  {
    key: "ai-receptionist",
    route: "ai-receptionist",
    icon: "bot",
    title: "Your AI Voice Employee",
    body: "This is the brain. Set its greeting, business hours, the languages it speaks, the knowledge it answers from, and exactly what it's allowed to do. Start here.",
  },
  {
    key: "tenant-calls",
    route: "tenant-calls",
    icon: "phone",
    title: "Every call, captured",
    body: "Recordings and transcripts for every call. You see both what was heard and what the AI understood — so nothing important slips through.",
  },
  {
    key: "tenant-intelligence",
    route: "tenant-intelligence",
    icon: "chart",
    title: "Demand intelligence",
    body: "The payoff. Across all your calls, discover what customers keep asking for, where demand is rising, and the opportunities you'd otherwise miss.",
  },
  {
    key: "tenant-actions",
    route: "tenant-actions",
    icon: "shield",
    title: "Actions waiting for you",
    body: "When the AI drafts a follow-up — an SMS, an email, a booking — it lands here for your approval before anything is sent on your behalf.",
  },
  {
    key: "tenant-routing",
    route: "tenant-routing",
    icon: "settings",
    title: "Send work to the right team",
    body: "Route each call's follow-ups to the right department automatically, with urgency levels and response targets so nothing stalls.",
  },
  {
    key: "outbound",
    route: "outbound",
    icon: "phone",
    title: "Let your AI make calls too",
    body: "Run outbound campaigns. Mikaka auto-drafts a tailored call guide for each recipient, so every call stays on message.",
  },
  {
    key: "research",
    route: "research",
    icon: "chart",
    title: "Studies & surveys",
    body: "Run phone surveys with an AI interviewer and get clean, structured results back — no manual dialing required.",
  },
  {
    key: "tenant-numbers",
    route: "tenant-numbers",
    icon: "hash",
    title: "Numbers & billing",
    body: "Your phone numbers live here. Top up your wallet and manage your plan under Billing whenever you need to.",
  },
  {
    key: "finish",
    route: null,
    icon: "check",
    title: "You're all set",
    body: "Fine-tune anything in Settings, and reach our team from Support. You can replay this tour anytime via \"Take a tour\" in your profile menu.",
    next: "Set up my AI",
    finishRoute: "ai-receptionist",
  },
];

const TOUR_CSS = `
@keyframes mk-tour-card-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes mk-tour-ring { 0%,100% { box-shadow: 0 0 0 9999px rgba(7,8,12,.60), 0 0 0 2px var(--mk-orange), 0 0 0 6px rgba(242,118,33,.18); } 50% { box-shadow: 0 0 0 9999px rgba(7,8,12,.60), 0 0 0 2px var(--mk-orange), 0 0 0 10px rgba(242,118,33,.05); } }
.mk-tour-backdrop { position: fixed; inset: 0; z-index: 9990; }
.mk-tour-ring { position: fixed; z-index: 9991; border-radius: 10px; pointer-events: none; transition: top .28s cubic-bezier(.4,0,.2,1), left .28s cubic-bezier(.4,0,.2,1), width .28s, height .28s; animation: mk-tour-ring 2.4s ease-in-out infinite; }
.mk-tour-card { position: fixed; z-index: 9992; width: 360px; max-width: calc(100vw - 32px); background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-lg); padding: 18px 18px 16px; animation: mk-tour-card-in .26s cubic-bezier(.4,0,.2,1) both; }
.mk-tour-card .eyebrow { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.mk-tour-card .eyebrow .chip-ic { width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center; background: var(--accent-soft, rgba(242,118,33,.1)); color: var(--mk-orange); flex-shrink: 0; }
.mk-tour-card .eyebrow .step-of { font-size: 11px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-faint); }
.mk-tour-card h3 { margin: 0 0 6px; font-size: 17px; font-weight: 600; letter-spacing: -0.01em; color: var(--fg); font-family: var(--font-display, inherit); }
.mk-tour-card p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--fg-muted); }
.mk-tour-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; }
.mk-tour-dots { display: flex; gap: 6px; }
.mk-tour-dots i { width: 6px; height: 6px; border-radius: 999px; background: var(--border); transition: background .2s, width .2s; }
.mk-tour-dots i.on { background: var(--mk-orange); width: 16px; }
.mk-tour-skip { position: absolute; top: 14px; right: 14px; }
@media (max-width: 900px) {
  .mk-tour-card { left: 50% !important; transform: translateX(-50%); bottom: 16px; top: auto !important; }
}
`;

function TenantTour({ onGo, route, userType }) {
  const [active, setActive] = useState(false);
  const [step, setStep] = useState(0);
  const [rect, setRect] = useState(null);
  const startedRef = useRef(false);
  const onGoRef = useRef(onGo);
  onGoRef.current = onGo;

  const total = TENANT_TOUR_STEPS.length;
  const current = TENANT_TOUR_STEPS[step] || TENANT_TOUR_STEPS[0];

  const markSeen = () => { try { localStorage.setItem(TOUR_SEEN_KEY, "1"); } catch {} };

  const begin = useCallback((index = 0) => {
    setStep(index);
    setActive(true);
    const target = TENANT_TOUR_STEPS[index];
    if (target && target.route && onGoRef.current) onGoRef.current(target.route);
  }, []);

  const close = useCallback(() => {
    setActive(false);
    markSeen();
  }, []);

  /* Relaunch from the "Take a tour" menu items. */
  useEffect(() => {
    const handler = () => { startedRef.current = true; begin(0); };
    window.addEventListener("mk-start-tour", handler);
    return () => window.removeEventListener("mk-start-tour", handler);
  }, [begin]);

  /* Auto-start once when a tenant first reaches their dashboard. */
  useEffect(() => {
    if (startedRef.current) return;
    if (userType !== "tenant") return;
    if (route !== "tenant-dashboard") return;
    let seen = false;
    try { seen = Boolean(localStorage.getItem(TOUR_SEEN_KEY)); } catch {}
    if (seen) return;
    startedRef.current = true;
    markSeen(); // never auto-start again, even if they refresh mid-tour
    const t = setTimeout(() => begin(0), 900);
    return () => clearTimeout(t);
  }, [route, userType, begin]);

  /* Locate and size the spotlight target for the current step. Returns null
     for centered steps (no route), below the mobile breakpoint, or while the
     target isn't laid out yet. Dedupes so an unchanged rect never re-renders. */
  const measure = useCallback(() => {
    const target = TENANT_TOUR_STEPS[step];
    if (!active || !target || !target.route || window.innerWidth <= 900) { setRect(null); return; }
    const el = document.querySelector(`[data-tour="${target.route}"]`);
    if (!el) { setRect(null); return; }
    const r = el.getBoundingClientRect();
    if (!r.width || !r.height) { setRect(null); return; }
    setRect(prev =>
      prev && prev.left === r.left && prev.top === r.top && prev.width === r.width && prev.height === r.height
        ? prev
        : { left: r.left, top: r.top, width: r.width, height: r.height }
    );
  }, [active, step]);

  /* Bring the target nav item into view once when the step changes. */
  useEffect(() => {
    if (!active) return;
    const target = TENANT_TOUR_STEPS[step];
    if (!target || !target.route) return;
    const el = document.querySelector(`[data-tour="${target.route}"]`);
    try { el && el.scrollIntoView({ block: "nearest" }); } catch {}
  }, [active, step]);

  /* Keep the spotlight aligned while the tour is up. A short poll makes this
     robust to async page renders after navigation and any layout shift,
     without depending on rAF timing; the dedupe in measure() keeps it cheap. */
  useEffect(() => {
    if (!active) return;
    measure();
    const id = setInterval(measure, 200);
    const onMove = () => measure();
    window.addEventListener("resize", onMove);
    window.addEventListener("scroll", onMove, true);
    return () => {
      clearInterval(id);
      window.removeEventListener("resize", onMove);
      window.removeEventListener("scroll", onMove, true);
    };
  }, [active, step, measure]);

  /* Lock background scroll while the tour is up. */
  useEffect(() => {
    if (!active) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = prev; };
  }, [active]);

  const goNext = () => {
    if (step >= total - 1) {
      const finishRoute = current.finishRoute;
      close();
      if (finishRoute && onGoRef.current) onGoRef.current(finishRoute);
      return;
    }
    begin(step + 1);
  };
  const goBack = () => { if (step > 0) begin(step - 1); };

  if (!active) return null;

  const isFirst = step === 0;
  const isLast = step === total - 1;
  const nextLabel = current.next || (isLast ? "Finish" : "Next");

  // Position the coach card relative to the spotlight (desktop) or as a
  // bottom sheet (mobile / centered steps). measure() already nulls `rect`
  // below 900px (fresh width read), and the CSS @media forces the bottom-sheet
  // layout there — so positioning keys off `rect` alone, never the mobile state.
  const cardStyle = {};
  if (rect) {
    const GAP = 14;
    const cardW = 360;
    let left = rect.left + rect.width + GAP;
    if (left + cardW > window.innerWidth - 16) {
      left = Math.max(16, rect.left - cardW - GAP);
    }
    const top = Math.min(Math.max(16, rect.top - 6), window.innerHeight - 260);
    cardStyle.left = left;
    cardStyle.top = top;
  } else {
    // Centered (welcome / finish / no target found)
    cardStyle.left = "50%";
    cardStyle.top = "50%";
    cardStyle.transform = "translate(-50%, -50%)";
  }

  return ReactDOM.createPortal(
    <React.Fragment>
      <style>{TOUR_CSS}</style>
      <div className="mk-tour-backdrop" style={{ background: rect ? "transparent" : "rgba(7,8,12,.45)" }} onClick={(e) => e.stopPropagation()} />
      {rect && (
        <div
          className="mk-tour-ring"
          style={{ left: rect.left - 5, top: rect.top - 5, width: rect.width + 10, height: rect.height + 10 }}
        />
      )}
      <div className="mk-tour-card" style={cardStyle} role="dialog" aria-modal="true" aria-label={current.title}>
        <button className="btn btn-ghost btn-icon btn-sm mk-tour-skip" onClick={close} aria-label="Close tour">
          <Icon name="x" size={15} />
        </button>
        <div className="eyebrow">
          <span className="chip-ic"><Icon name={current.icon} size={16} /></span>
          <span className="step-of">{`Step ${step + 1} of ${total}`}</span>
        </div>
        <h3>{current.title}</h3>
        <p>{current.body}</p>
        <div className="mk-tour-foot">
          <div className="mk-tour-dots" aria-hidden="true">
            {TENANT_TOUR_STEPS.map((s, i) => (
              <i key={s.key} className={i === step ? "on" : ""} />
            ))}
          </div>
          <div className="row" style={{ display: "flex", alignItems: "center", gap: 8 }}>
            {isFirst ? (
              <button className="btn btn-ghost btn-sm" onClick={close}>Skip</button>
            ) : (
              <button className="btn btn-outline btn-sm" onClick={goBack}>Back</button>
            )}
            <button className="btn btn-accent btn-sm" onClick={goNext}>
              {nextLabel}{!isLast && <Icon name="arrow-right" size={14} style={{ marginLeft: 6 }} />}
            </button>
          </div>
        </div>
      </div>
    </React.Fragment>,
    document.body
  );
}

window.TenantTour = TenantTour;
