// ============================================================
// tour-overlay.jsx · componente guiado con spotlight + tooltip
// Vive en el shell padre · habla con tour-bridge.js en cada iframe
// ============================================================

// === Datos de los tours por flujo ===
// target.kind: "shell" (DOM del padre) | "iframe" (DOM dentro del iframe activo)
// target.selector: CSS selector — preferimos [data-tour="..."] para resistir cambios
// position: lado preferido del tooltip relativo al spotlight
const TOURS = {
  comunicados: {
    title: "Comunicados que sí se leen",
    role: "director-op",
    section: "broadcast",
    steps: [
      {
        target: { kind: "iframe", selector: '[data-tour="bc-segment"]' },
        position: "right",
        title: "1 · Empezamos por destinatarios",
        body: "Norma elige quién recibe el aviso — toda la comunidad, un nivel, un grupo o familias específicas. Multi-tutor: si un alumno tiene dos tutores, ambos reciben.",
        action: { kind: "selectSegment", value: "padres-all" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="bc-ai"]' },
        position: "right",
        title: "2 · Xokai AI redacta por ti",
        body: "En vez de escribir desde cero, Norma le dicta a la IA en lenguaje natural lo que quiere comunicar.",
        ai: true,
        action: { kind: "aiOpen" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="bc-message"]' },
        position: "left",
        title: "3 · El borrador, listo",
        body: "Xokai AI redacta el comunicado claro y segmentado por nivel — y lo marca como crítico para que nadie se lo pierda.",
        ai: true,
        action: { kind: "aiGenerate" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="bc-preview"]' },
        position: "left",
        title: "4 · Así lo ve la familia",
        body: "Vista previa exacta del aviso branded Hábitat antes de enviar. Llega como push al celular + email.",
      },
      {
        target: { kind: "iframe", selector: '[data-tour="bc-send"]' },
        position: "top",
        title: "5 · Enviar a la comunidad",
        body: "Un solo envío llega a los 614 tutores de las 325 familias. Veamos qué pasa después.",
      },
      {
        target: { kind: "iframe", selector: '[data-tour="bc-calendar"]' },
        position: "top",
        title: "6 · Todo junio, de un vistazo",
        body: "Cada día con su color. Al tocar el 11 se abre la explicación por nivel: preescolar y primaria sin clases · secundaria con actividad opcional. Esto es lo que el PDF no podía hacer.",
        action: { kind: "expandDay", day: 11 },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="bc-receipts"]' },
        position: "bottom",
        title: "7 · Quién leyó, en vivo",
        body: "287 de 325 familias ya leyeron. Con un toque Norma le recuerda a las que faltan — sin perseguir a nadie por WhatsApp.",
        action: { kind: "send" },
      },
    ],
  },

  pickup: {
    title: "Pickup sin filas",
    role: "padre",
    section: "m3-pickup",
    steps: [
      {
        target: { kind: "iframe", selector: '[data-tour="pu-hero"]' },
        position: "right",
        title: "1 · Tu rol de hoy, en verde",
        body: "La familia abre la app y en un vistazo sabe quién recoge a quién. Hoy: Ezdraz por Vania, Karina por Elián. Confirmado.",
        action: { kind: "reset" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pu-windows"]' },
        position: "right",
        title: "2 · Salidas escalonadas",
        body: "Cada nivel sale a su hora — Preescolar 14:00, Primaria menor 14:30, mayor 15:00, Secundaria 15:30. Las ventanas de la familia van resaltadas. Sin filas en la puerta.",
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pu-actions"]' },
        position: "right",
        title: "3 · Cambiar quién recoge",
        body: "¿Surge un imprevisto? Con un toque Vania pasa a Karina y el rol se actualiza para todos al instante.",
        action: { kind: "pasarKarina" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pu-tercero"]' },
        position: "right",
        title: "4 · Tercero temporal con QR",
        body: "Para un playdate, la familia autoriza a un tercero solo por hoy. Karina lo aprueba, el portero valida con QR y el permiso se auto-revoca. Esto no existe en LATAM.",
        action: { kind: "openTercero" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pu-ai"]' },
        position: "right",
        title: "5 · Xokai aprende el patrón",
        body: "Xokai nota que los lunes Vania se va con María y ofrece programarlo. Hacia allá va — por ahora es una sugerencia.",
        ai: true,
        action: { kind: "aiSuggest" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pu-timeline"]' },
        position: "right",
        title: "6 · Todo queda registrado",
        body: "Cada entrada y salida queda con hora y responsable. Si alguien pregunta quién recogió a quién, la respuesta ya está aquí.",
      },
    ],
  },

  pagos: {
    title: "Pagos desde el celular",
    role: "padre",
    section: "m6-pagos",
    steps: [
      {
        target: { kind: "iframe", selector: '[data-tour="pg-hero"]' },
        position: "right",
        title: "1 · Tu estado de cuenta, claro",
        body: "Lo que la familia debe este mes en un solo número: $22,570, vence el 5 de junio. Sin estados de cuenta confusos ni sorpresas.",
        action: { kind: "reset" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pg-split"]' },
        position: "right",
        title: "2 · Pago compartido entre tutores",
        body: "Ezdraz y Karina dividen la colegiatura. La app muestra quién ya pagó su mitad y quién falta — sin cobranzas incómodas entre ellos.",
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pg-ai"]' },
        position: "right",
        title: "3 · Xokai predice morosidad",
        body: "Xokai aprende cuándo suele atrasarse cada familia y propone recordar antes del día 5. Hacia allá va — hoy es una sugerencia.",
        ai: true,
        action: { kind: "aiPredict" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="pg-pay"]' },
        position: "right",
        title: "4 · Pago en 3 toques, CFDI automático",
        body: "Un toque para pagar, MSI hasta 12 meses, y el CFDI se genera y se envía solo. Karina recibe su comprobante sin pedirlo.",
      },
    ],
  },

  maestro: {
    title: "Maestro y familia, sin saturar",
    role: "maestro",
    section: "m3",
    steps: [
      {
        target: { kind: "iframe", selector: '[data-tour="mt-inbox"]' },
        position: "right",
        title: "1 · Una bandeja, no un grupo de WhatsApp",
        body: "Mensajes con familias y avisos enviados, separados. Sin grupo de padres muteado ni hilos perdidos — cada conversación es por niño.",
        action: { kind: "reset" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="mt-limits"]' },
        position: "right",
        title: "2 · DMs con límites",
        body: "Horario de atención visible, sin exponer el número personal del maestro, y fuera de horario no llegan notificaciones. La escuela conserva cada hilo por transparencia.",
        action: { kind: "openThread" },
      },
      {
        target: { kind: "iframe", selector: '[data-tour="mt-escalate"]' },
        position: "right",
        title: "3 · Tema sensible · escalar a Director",
        body: "Si una conversación lo amerita, el maestro la escala al Director con un toque — el hilo completo y la etiqueta viajan con ella. Nadie queda solo con un tema delicado.",
      },
    ],
  },

  setup: {
    title: "Tu escuela montada en 30 min",
    role: "sysadmin",
    section: null,
    steps: [
      {
        target: { kind: "shell", selector: '[data-tour="su-invite"]' },
        position: "left",
        title: "1 · Xokai da de alta tu escuela",
        body: "Xokai captura los datos fiscales y envía un magic link al correo de Norma. Un clic y entra a configurar — sin instalar nada.",
        action: { kind: "goto", id: "A4" },
      },
      {
        target: { kind: "shell", selector: '[data-tour="su-welcome"]' },
        position: "bottom",
        title: "2 · Norma entra a su onboarding",
        body: "Norma abre el link y un asistente la lleva paso a paso. Tiempo estimado: 25 a 30 minutos, y puede guardar y volver cuando quiera.",
        action: { kind: "goto", id: "B0" },
      },
      {
        target: { kind: "shell", selector: '[data-tour="su-brand"]' },
        position: "right",
        title: "3 · La app se ve como Hábitat",
        body: "Xokai detecta los colores del logo de Hábitat y deja la app branded — verde, isotipo y dominio propio. Xokai se queda detrás operando.",
        action: { kind: "goto", id: "B2" },
      },
      {
        target: { kind: "shell", selector: '[data-tour="su-structure"]' },
        position: "top",
        title: "4 · Tu estructura, pre-armada",
        body: "Niveles y grupos vienen sugeridos según la pedagogía de Hábitat: 4 niveles, 13 grupos. Norma solo ajusta y confirma.",
        action: { kind: "goto", id: "B3" },
      },
      {
        target: { kind: "shell", selector: '[data-tour="su-pickup"]' },
        position: "right",
        title: "5 · Pickup escalonado · el diferenciador",
        body: "Cada nivel sale en su ventana de 30 minutos. Se arma solo a partir de la estructura — y es lo que el PDF y el grupo de WhatsApp nunca pudieron hacer.",
        action: { kind: "goto", id: "B5" },
      },
      {
        target: { kind: "shell", selector: '[data-tour="su-done"]' },
        position: "top",
        title: "6 · Lista en menos de 30 min",
        body: "Branding, estructura, ciclo y pickup configurados. Hábitat queda montada en Xokai más rápido que un café.",
        action: { kind: "goto", id: "B7" },
      },
    ],
  },
};

window.HABITAT_TOURS = TOURS;

// ============================================================
// TourOverlay component
// Props:
//   tourKey: string (key into TOURS)
//   getIframe: () => HTMLIFrameElement | null  (para postMessage)
//   onFinish: () => void
// ============================================================
function TourOverlay({ tourKey, getIframe, onFinish }) {
  const tour = TOURS[tourKey];
  const [stepIdx, setStepIdx] = useState(0);
  const [rect, setRect] = useState(null);
  const [iframeRect, setIframeRect] = useState(null);
  const step = tour && tour.steps[stepIdx];

  // re-mide el iframe cuando cambia tamaño de ventana
  useEffect(() => {
    function measureIframe() {
      const fr = getIframe && getIframe();
      if (fr) setIframeRect(fr.getBoundingClientRect());
    }
    measureIframe();
    window.addEventListener("resize", measureIframe);
    // poll por si el iframe aún no estaba en DOM
    const id = setInterval(measureIframe, 500);
    return () => { window.removeEventListener("resize", measureIframe); clearInterval(id); };
  }, [getIframe]);

  // dispara la acción del step (una sola vez por step) — actualiza el fondo
  useEffect(() => {
    if (!step || !step.action) return;
    // shell: la pantalla vive en el padre · navegamos con window.goTo
    if (step.target.kind === "shell") {
      if (step.action.kind === "goto" && step.action.id && window.goTo) window.goTo(step.action.id);
      return;
    }
    const fr = getIframe && getIframe();
    if (!fr || !fr.contentWindow) return;
    const send = () => fr.contentWindow.postMessage({ type: "xk-tour-action", action: step.action }, "*");
    // pequeño retry por si el bridge aún no engancha
    send();
    const t1 = setTimeout(send, 120);
    return () => clearTimeout(t1);
  }, [stepIdx]);

  // localiza el target del step actual
  useEffect(() => {
    if (!step) return;
    setRect(null);
    if (step.target.kind === "shell") {
      // selector en el padre
      const tryFind = () => {
        const el = document.querySelector(step.target.selector);
        if (el) {
          const r = el.getBoundingClientRect();
          if (r.width > 0) {
            setRect({ x: r.left, y: r.top, w: r.width, h: r.height });
            return true;
          }
        }
        return false;
      };
      if (tryFind()) return;
      // retry hasta 10 veces
      let attempts = 0;
      const id = setInterval(() => {
        if (tryFind() || ++attempts > 10) clearInterval(id);
      }, 200);
      return () => clearInterval(id);
    }

    if (step.target.kind === "iframe") {
      const fr = getIframe && getIframe();
      if (!fr || !fr.contentWindow) return;
      // pide rect al bridge dentro del iframe
      const askLocate = () => {
        fr.contentWindow.postMessage({ type: "xk-tour-locate", selector: step.target.selector }, "*");
      };
      askLocate();
      // re-pregunta cada 500ms hasta tener respuesta (max 5s)
      let attempts = 0;
      const id = setInterval(() => {
        if (rect || ++attempts > 10) clearInterval(id);
        else askLocate();
      }, 500);
      return () => clearInterval(id);
    }
  }, [stepIdx, getIframe]);

  // escucha respuestas del bridge
  useEffect(() => {
    function onMsg(e) {
      const d = e.data;
      if (!d || typeof d !== "object") return;
      if (d.type === "xk-tour-rect" && step && step.target.kind === "iframe" && d.selector === step.target.selector) {
        if (d.rect) {
          setRect({ x: d.rect.x, y: d.rect.y, w: d.rect.w, h: d.rect.h });
        }
      }
      if (d.type === "xk-tour-next") {
        next();
      }
    }
    window.addEventListener("message", onMsg);
    return () => window.removeEventListener("message", onMsg);
  }, [step, stepIdx]);

  if (!tour || !step) return null;

  function next() {
    if (stepIdx < tour.steps.length - 1) setStepIdx(stepIdx + 1);
    else onFinish && onFinish();
  }
  function prev() {
    if (stepIdx > 0) setStepIdx(stepIdx - 1);
  }
  function skip() {
    onFinish && onFinish();
  }

  // Calcula coords absolutas del spotlight en el viewport del padre
  let absRect = null;
  if (rect) {
    if (step.target.kind === "iframe" && iframeRect) {
      absRect = {
        x: iframeRect.left + rect.x,
        y: iframeRect.top + rect.y,
        w: rect.w,
        h: rect.h,
      };
    } else if (step.target.kind === "shell") {
      absRect = rect;
    }
  }

  const PAD = 8;
  const vw = window.innerWidth, vh = window.innerHeight;

  // Tooltip dimensions
  const TT_W = 360;
  const TT_GAP = 16;

  // Position tooltip
  let ttx = vw / 2 - TT_W / 2, tty = vh / 2 - 80;
  if (absRect && step.position !== "center") {
    if (step.position === "right") {
      ttx = absRect.x + absRect.w + TT_GAP;
      tty = absRect.y;
    } else if (step.position === "left") {
      ttx = absRect.x - TT_W - TT_GAP;
      tty = absRect.y;
    } else if (step.position === "top") {
      ttx = absRect.x + absRect.w / 2 - TT_W / 2;
      tty = absRect.y - 180;
    } else if (step.position === "bottom") {
      ttx = absRect.x + absRect.w / 2 - TT_W / 2;
      tty = absRect.y + absRect.h + TT_GAP;
    }
    // clamp dentro del viewport
    ttx = Math.max(16, Math.min(ttx, vw - TT_W - 16));
    tty = Math.max(16, Math.min(tty, vh - 220));
  }

  // SVG mask: rect cubre todo, el hueco se hace con evenodd
  const holeX = absRect ? absRect.x - PAD : -1000;
  const holeY = absRect ? absRect.y - PAD : -1000;
  const holeW = absRect ? absRect.w + PAD * 2 : 0;
  const holeH = absRect ? absRect.h + PAD * 2 : 0;
  const holeR = 10;

  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: 9999,
      pointerEvents: "auto",
      fontFamily: "var(--xk-font-sans)",
    }}>
      {/* Mask oscuro con hueco — usa SVG y fill-rule evenodd */}
      <svg width={vw} height={vh} style={{ position: "absolute", inset: 0, display: "block" }}>
        <defs>
          <mask id="hbt-tour-hole">
            <rect x="0" y="0" width={vw} height={vh} fill="white" />
            {absRect && (
              <rect x={holeX} y={holeY} width={holeW} height={holeH} rx={holeR} ry={holeR} fill="black" />
            )}
          </mask>
        </defs>
        <rect x="0" y="0" width={vw} height={vh}
              fill="rgba(15,14,12,0.62)"
              mask="url(#hbt-tour-hole)" />
        {absRect && (
          <rect x={holeX} y={holeY} width={holeW} height={holeH} rx={holeR} ry={holeR}
                fill="none"
                stroke="#88B83C"
                strokeWidth="2"
                style={{ filter: "drop-shadow(0 0 12px rgba(136,184,60,0.55))" }} />
        )}
      </svg>

      {/* Botón skip flotante (X) */}
      <button onClick={skip} title="Saltar tour" style={{
        position: "absolute", top: 20, right: 24,
        width: 36, height: 36, borderRadius: 999,
        border: "none", background: "rgba(255,255,255,0.92)",
        cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center",
        boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
      }}>
        <Icon name="x" size={18} color="#04342C" />
      </button>

      {/* Header del tour (título del flujo + progreso) */}
      <div style={{
        position: "absolute", top: 24, left: 28,
        display: "inline-flex", alignItems: "center", gap: 10,
        padding: "8px 14px", borderRadius: 999,
        background: "rgba(255,255,255,0.96)",
        boxShadow: "0 2px 10px rgba(0,0,0,0.18)",
        fontSize: 12.5, fontWeight: 600, color: "#04342C",
      }}>
        <span style={{ display: "inline-flex", width: 18, height: 18, alignItems: "center", justifyContent: "center" }}>
          <Icon name="compass" size={14} color="#88B83C" />
        </span>
        Tour · {tour.title}
        <span style={{ color: "var(--xk-text-muted)", fontWeight: 500, fontFamily: "var(--xk-font-mono)" }}>
          {stepIdx + 1} / {tour.steps.length}
        </span>
      </div>

      {/* Tooltip */}
      <div style={{
        position: "absolute",
        left: ttx, top: tty,
        width: TT_W,
        background: "#FFFFFF",
        border: "1px solid #E1F5EE",
        borderRadius: 14,
        padding: 18,
        boxShadow: "0 16px 36px rgba(15,14,12,0.18), 0 4px 8px rgba(15,14,12,0.06)",
        animation: "hbt-tour-pop 240ms cubic-bezier(0.16,1,0.3,1)",
      }}>
        {step.ai && (
          <div style={{
            display: "inline-flex", alignItems: "center", gap: 5,
            padding: "3px 8px", borderRadius: 999,
            background: "linear-gradient(90deg, #E1F5EE, #F7FBEE)",
            border: "1px solid color-mix(in oklab, #88B83C 25%, transparent)",
            fontSize: 10.5, fontWeight: 700, color: "#04342C",
            letterSpacing: "0.04em", textTransform: "uppercase",
            marginBottom: 8,
          }}>
            <Icon name="sparkles" size={11} color="#88B83C" />
            Xokai AI · próximamente
          </div>
        )}
        <h3 style={{
          margin: "0 0 8px",
          fontSize: 15.5, fontWeight: 600,
          color: "#04342C", letterSpacing: "-0.01em",
          lineHeight: 1.3,
        }}>
          {step.title}
        </h3>
        <p style={{
          margin: 0,
          fontSize: 13, lineHeight: 1.55,
          color: "var(--xk-text-secondary)",
        }}>
          {step.body}
        </p>
        <div style={{
          marginTop: 14, paddingTop: 12, borderTop: "1px solid #E1F5EE",
          display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8,
        }}>
          <button onClick={skip} style={{
            border: "none", background: "transparent", padding: "6px 4px",
            fontSize: 12, color: "var(--xk-text-muted)", cursor: "pointer",
            textDecoration: "underline", fontFamily: "inherit",
          }}>Saltar tour</button>
          <div style={{ display: "inline-flex", gap: 8 }}>
            {stepIdx > 0 && (
              <button onClick={prev} style={{
                padding: "8px 12px", borderRadius: 8,
                border: "1px solid var(--xk-border)",
                background: "var(--xk-surface)", cursor: "pointer",
                fontSize: 12.5, fontWeight: 500, color: "var(--xk-text-secondary)",
                fontFamily: "inherit",
              }}>← Atrás</button>
            )}
            <button onClick={next} style={{
              padding: "8px 14px", borderRadius: 8,
              border: "none", background: "#88B83C", color: "#FFFFFF",
              cursor: "pointer", fontSize: 12.5, fontWeight: 600,
              fontFamily: "inherit",
              display: "inline-flex", alignItems: "center", gap: 5,
            }}>
              {stepIdx === tour.steps.length - 1 ? "Terminar" : "Siguiente"}
              <Icon name="arrow-right" size={13} />
            </button>
          </div>
        </div>
      </div>

      <style>{`
        @keyframes hbt-tour-pop {
          0% { transform: translateY(6px) scale(0.97); opacity: 0; }
          100% { transform: translateY(0) scale(1); opacity: 1; }
        }
        @media (prefers-reduced-motion: reduce) {
          @keyframes hbt-tour-pop { 0%,100% { transform: none; opacity: 1; } }
        }
      `}</style>
    </div>
  );
}

window.TourOverlay = TourOverlay;
