/* global React, Icon */
const { useState: useS, useEffect: useE, useRef: useR } = React;

/* ============================================================
   DATA — single source of truth across pages
   ============================================================ */
const EXPERTS = [
  {
    id: "sebastian", initials: "SC", name: "Sebastián Carrillo",
    role: "Marketing · IA · Analytics", hue: 162,
    tags: ["Marketing", "IA", "Analytics"],
    quote: "Los datos no mienten. Las corazonadas, a veces sí.",
    bio: "Estratega de marketing y analítica con más de una década moviendo métricas que importan. Convierte dashboards en decisiones.",
    avail: "Disponible Lun–Jue 18–21h", rating: "4.9", icon: "chart",
  },
  {
    id: "antonio", initials: "AR", name: "Antonio Rada",
    role: "Ventas Estratégicas", hue: 28,
    tags: ["Ventas", "Estrategia", "CRM"],
    quote: "No persigas clientes. Haz que te busquen.",
    bio: "Especialista en ventas consultivas y procesos comerciales. Ha cerrado y enseñado a cerrar en mercados que otros dan por perdidos.",
    avail: "Disponible Lun–Jue 18–21h", rating: "4.9", icon: "trendingUp",
  },
  {
    id: "ana", initials: "AP", name: "Ana Pérez",
    role: "Marca Personal · Marketing Corp.", hue: 268,
    tags: ["Marca Personal", "Branding", "Storytelling"],
    quote: "Tu marca empieza con una sola frase. Hazla buena.",
    bio: "Constructora de marcas personales y corporativas. Toma profesionales invisibles y los vuelve referentes de su industria.",
    avail: "Disponible Lun–Jue 18–21h", rating: "4.8", icon: "sparkles",
  },
  {
    id: "jorge", initials: "JC", name: "Jorge Luis Contreras",
    role: "IA · Sistematización", hue: 205,
    tags: ["IA", "Automatización", "No-code"],
    quote: "La IA no te reemplaza. Quien sabe usarla, sí.",
    bio: "Ingeniero de sistemas y automatización. Diseña flujos inteligentes que le devuelven horas a tu semana, sin escribir una línea de código.",
    avail: "Disponible Lun–Jue 18–21h", rating: "5.0", icon: "workflow",
  },
  {
    id: "valeria", initials: "VG", name: "Valeria González",
    role: "Sostenibilidad · ESG", hue: 130,
    tags: ["Sostenibilidad", "ESG", "Certificaciones"],
    quote: "ESG no es un gasto. Es tu próxima ventaja.",
    bio: "Consultora ambiental y guía de certificaciones ESG. Acompaña a empresas a volverse sostenibles de verdad, paso a paso.",
    avail: "Disponible Lun–Jue 18–21h", rating: "4.9", icon: "leaf",
  },
];

const CAT_COLORS = {
  "IA & Tech": 205, "IA": 205, "Marketing": 162, "Ventas": 28,
  "Marca Personal": 268, "Marca": 268, "Sostenibilidad": 130, "ESG": 130,
  "Sistematización": 195, "Productividad": 40,
};

const COURSES = [
  { id: "ia-negocio", cat: "IA & Tech", icon: "sparkles", title: "IA para tu negocio: de concepto a implementación real", instructors: ["jorge", "sebastian"], price: 197, badge: "NEW", rating: "4.9", students: "312", modules: 6, hours: "4h" },
  { id: "data-marketing", cat: "Marketing", icon: "chart", title: "Data Marketing: decide con datos, no con corazonadas", instructors: ["sebastian"], price: 157, rating: "4.8", students: "289", modules: 5, hours: "3h" },
  { id: "ventas-sin-presion", cat: "Ventas", icon: "trendingUp", title: "Ventas sin presión: cierra más sin perseguir clientes", instructors: ["antonio"], price: 127, badge: "POPULAR", rating: "4.8", students: "234", modules: 5, hours: "2.5h" },
  { id: "marca-referente", cat: "Marca Personal", icon: "sparkles", title: "De experto a referente: construye tu marca en 90 días", instructors: ["ana"], price: 137, rating: "4.9", students: "198", modules: 6, hours: "3.5h" },
  { id: "esg-certificaciones", cat: "Sostenibilidad", icon: "leaf", title: "Certificaciones ESG: posiciona tu empresa como sostenible", instructors: ["valeria"], price: 147, rating: "4.9", students: "142", modules: 5, hours: "3h" },
  { id: "automatiza", cat: "Sistematización", icon: "workflow", title: "Automatiza tu empresa: flujos inteligentes sin código", instructors: ["jorge"], price: 167, rating: "5.0", students: "176", modules: 6, hours: "4h" },
];

const expertById = (id) => EXPERTS.find((e) => e.id === id);
const courseById = (id) => COURSES.find((c) => c.id === id);

/* Contact / social — single place to update real handles later */
const CONTACT = {
  email: "hola@itsmarketproof.com",
  // TODO: reemplazar con el número de WhatsApp real (formato internacional, sin "+" ni espacios)
  whatsapp: "https://wa.me/50212345678",
  instagram: "https://instagram.com/itsmarketproof",
  linkedin: "https://www.linkedin.com/company/itsmarketproof",
  youtube: "https://youtube.com/@itsmarketproof",
  tiktok: "https://tiktok.com/@itsmarketproof",
};

/* ============================================================
   PRIMITIVES
   ============================================================ */
function Avatar({ initials, hue = 200, size = 56, ring = false, fontScale = 0.34 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 999,
      background: `linear-gradient(140deg, hsl(${hue} 42% 86%), hsl(${hue} 36% 74%))`,
      color: "var(--mp-ink)", display: "flex", alignItems: "center", justifyContent: "center",
      fontWeight: 800, fontSize: Math.round(size * fontScale), letterSpacing: "-0.02em",
      flex: "0 0 auto",
      boxShadow: ring ? "0 0 0 3px rgba(255,255,255,0.9), var(--mp-shadow-sm)" : "none",
    }}>{initials}</div>
  );
}

function Eyebrow({ children, onDark = false, style }) {
  return (
    <div style={{
      fontSize: 12, letterSpacing: "0.18em", textTransform: "uppercase", fontWeight: 700,
      color: onDark ? "var(--mp-mint)" : "var(--mp-slate)",
      display: "inline-flex", alignItems: "center", gap: 9, ...style,
    }}>
      <span style={{ width: 7, height: 7, borderRadius: 999, background: onDark ? "var(--mp-mint)" : "var(--mp-mint-deep)" }} />
      {children}
    </div>
  );
}

/* Headline with one mint-italic highlight word. Pass text with [brackets] around the word. */
function Flourish({ text, onDark = false, ...rest }) {
  const parts = text.split(/(\[[^\]]+\])/g);
  return (
    <span {...rest}>
      {parts.map((p, i) =>
        p.startsWith("[") ? (
          <span key={i} style={{ fontStyle: "italic", color: onDark ? "var(--mp-mint)" : "var(--mp-mint-deep)" }}>
            {p.slice(1, -1)}
          </span>
        ) : <React.Fragment key={i}>{p}</React.Fragment>
      )}
    </span>
  );
}

function Button({ children, variant = "mint", size = "md", onClick, href, icon, full = false, style, type = "button", disabled = false, target }) {
  const pad = size === "lg" ? "16px 30px" : size === "sm" ? "10px 18px" : "14px 24px";
  const fs = size === "lg" ? 16 : size === "sm" ? 13 : 14.5;
  const base = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 9,
    border: "0", borderRadius: 999, padding: pad, fontFamily: "var(--mp-font-sans)",
    fontWeight: 700, fontSize: fs, cursor: "pointer", textDecoration: "none",
    letterSpacing: "-0.005em", width: full ? "100%" : "auto", whiteSpace: "nowrap",
    transition: "box-shadow 220ms var(--mp-ease), transform 160ms var(--mp-ease), background-color 200ms",
  };
  const variants = {
    mint: { background: "var(--mp-mint)", color: "var(--mp-ink)", boxShadow: "0 1px 2px rgba(15,32,44,0.06)" },
    ink: { background: "var(--mp-ink)", color: "var(--mp-paper)", boxShadow: "0 1px 2px rgba(15,32,44,0.08)" },
    outlineWhite: { background: "rgba(255,255,255,0.04)", color: "var(--mp-paper)", border: "1.5px solid rgba(255,255,255,0.45)" },
    outlineInk: { background: "transparent", color: "var(--mp-ink)", border: "1.5px solid var(--mp-border-strong)" },
    ghostWhite: { background: "transparent", color: "var(--mp-paper)", padding: size === "sm" ? "10px 6px" : "14px 8px" },
    ghostInk: { background: "transparent", color: "var(--mp-ink)", padding: size === "sm" ? "10px 6px" : "14px 8px" },
  };
  const v = variants[variant] || variants.mint;
  const Tag = href ? "a" : "button";
  const rel = target === "_blank" ? "noopener noreferrer" : undefined;
  return (
    <Tag
      href={href} target={target} rel={rel}
      type={href ? undefined : type}
      disabled={href ? undefined : disabled}
      aria-disabled={disabled || undefined}
      onClick={disabled ? (e) => e.preventDefault() : onClick}
      className={"mpbtn mpbtn-" + variant}
      style={{ ...base, ...v, ...style, ...(disabled ? { opacity: 0.5, cursor: "not-allowed", boxShadow: "none" } : null) }}
    >
      {children}
      {icon && <Icon name={icon} size={size === "lg" ? 19 : 17} />}
    </Tag>
  );
}

function Pill({ children, active = false, onClick, onDark = false, hue, style }) {
  const tinted = hue != null;
  return (
    <button onClick={onClick} style={{
      border: tinted ? "0" : `1px solid ${active ? "transparent" : (onDark ? "var(--mp-border-onDark)" : "var(--mp-border-strong)")}`,
      background: active
        ? (onDark ? "var(--mp-mint)" : "var(--mp-ink)")
        : tinted ? `hsl(${hue} 50% 92%)`
        : (onDark ? "rgba(255,255,255,0.06)" : "var(--mp-paper)"),
      color: active ? (onDark ? "var(--mp-ink)" : "var(--mp-paper)")
        : tinted ? `hsl(${hue} 45% 28%)`
        : (onDark ? "rgba(255,255,255,0.82)" : "var(--mp-fg)"),
      borderRadius: 999, padding: "8px 16px", fontFamily: "var(--mp-font-sans)",
      fontWeight: 600, fontSize: 13, cursor: onClick ? "pointer" : "default",
      letterSpacing: "0.01em", transition: "all 200ms var(--mp-ease)", whiteSpace: "nowrap",
      ...style,
    }}>{children}</button>
  );
}

function Tag({ children, hue = 200, dark = false }) {
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6,
      background: dark ? "rgba(255,255,255,0.08)" : `hsl(${hue} 52% 93%)`,
      color: dark ? "rgba(255,255,255,0.85)" : `hsl(${hue} 42% 26%)`,
      borderRadius: 999, padding: "5px 12px", fontSize: 11.5, fontWeight: 600,
      letterSpacing: "0.02em", whiteSpace: "nowrap",
    }}>{children}</span>
  );
}

function Stars({ value = 5, size = 14, showNum = null, muted = false }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}>
      <span style={{ display: "inline-flex", gap: 1.5 }}>
        {[0, 1, 2, 3, 4].map((i) => (
          <Icon key={i} name="star" size={size}
            style={{ color: "var(--mp-mint-deep)", fill: i < Math.round(value) ? "var(--mp-mint-deep)" : "transparent" }} />
        ))}
      </span>
      {showNum && <span style={{ fontSize: size - 1, fontWeight: 700, color: muted ? "var(--mp-fg-muted)" : "inherit" }}>{showNum}</span>}
    </span>
  );
}

/* prefers-reduced-motion — evaluated once; scroll reveals become instant. */
const MP_REDUCED = typeof window !== "undefined" && window.matchMedia
  ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : false;

/* Scroll-triggered reveal wrapper.
   Backwards compatible: <Reveal delay y style as> still works exactly as before.
   New: variant="up|slide-left|slide-right|scale" (or pass x / scale directly),
        dur, threshold. Respects prefers-reduced-motion. */
const REVEAL_PRESETS = {
  up: { y: 34 },
  "slide-left": { x: -44, y: 0 },
  "slide-right": { x: 44, y: 0 },
  scale: { scale: 0.94, y: 14 },
};
function Reveal({ children, delay = 0, y = 16, x = 0, scale, variant, dur = 640, threshold = 0.12, style, className, as = "div" }) {
  const ref = useR(null);
  const [shown, setShown] = useS(MP_REDUCED);
  useE(() => {
    if (MP_REDUCED) return;
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } });
    }, { threshold, rootMargin: "0px 0px -8% 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const p = (variant && REVEAL_PRESETS[variant]) || {};
  const ty = p.y != null ? p.y : y;
  const tx = p.x != null ? p.x : x;
  const sc = scale != null ? scale : p.scale;
  const hidden = [
    ty ? `translateY(${ty}px)` : "",
    tx ? `translateX(${tx}px)` : "",
    sc ? `scale(${sc})` : "",
  ].filter(Boolean).join(" ") || "translateY(16px)";
  const Tag = as;
  return (
    <Tag ref={ref} className={className} style={{
      ...style,
      opacity: shown ? 1 : 0,
      transform: shown ? "none" : hidden,
      transition: `opacity ${dur}ms var(--mp-ease-emph) ${delay}ms, transform ${dur}ms var(--mp-ease-emph) ${delay}ms`,
      willChange: shown ? "auto" : "opacity, transform",
    }}>{children}</Tag>
  );
}

/* Scroll-progress hook — returns 0→1 as `ref` travels through the viewport.
   Used for the recruitment timeline progress line. rAF-throttled, reduced-motion safe. */
function useScrollProgress(ref) {
  const [p, setP] = useS(MP_REDUCED ? 1 : 0);
  useE(() => {
    if (MP_REDUCED) return;
    const el = ref.current;
    if (!el) return;
    let raf = 0;
    const calc = () => {
      raf = 0;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      const total = r.height + vh * 0.55;
      const seen = vh * 0.8 - r.top;
      setP(Math.max(0, Math.min(1, seen / total)));
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(calc); };
    calc();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return p;
}

/* Section shell that sets background + standard padding + max width */
function Section({ bg = "paper", children, id, style, inner = {}, pad = "96px 40px" }) {
  const bgs = { paper: "var(--mp-paper)", cloud: "var(--mp-cloud)", ink: "var(--mp-ink)", mint: "var(--mp-mint)" };
  const fg = bg === "ink" ? "var(--mp-paper)" : "var(--mp-ink)";
  return (
    <section id={id} style={{ background: bgs[bg], color: fg, padding: pad, ...style }}>
      <div style={{ maxWidth: 1240, margin: "0 auto", ...inner }}>{children}</div>
    </section>
  );
}

Object.assign(window, {
  EXPERTS, COURSES, CAT_COLORS, CONTACT, expertById, courseById,
  Avatar, Eyebrow, Flourish, Button, Pill, Tag, Stars, Reveal, Section,
  MP_REDUCED, useScrollProgress,
});
