// URL ⇆ route-state translation + <Link> for SPA navigation.
// Exposes window.__bbRouter = { parseRoute, buildPath, navigate, Link, titleFor, descFor }.
// Internal route names ("home" | "catalog" | "detail" | "booking" | "about" | "contact"
// | "journal" | "journal-post") map 1:1 to stable URL paths; slugs come from EXPERIENCES
// and JOURNAL in data.js.

(function () {
  const SITE = "Bacalar Beyond";

  function parseRoute(pathname) {
    const parts = (pathname || "/").split("/").filter(Boolean);
    if (parts.length === 0) return { route: "home" };
    const [a, b, c] = parts;

    if (a === "experiences") {
      if (!b) return { route: "catalog" };
      const exp = (window.EXPERIENCES || []).find((e) => e.slug === b);
      if (!exp) return { route: "catalog" };
      return { route: "detail", currentExp: exp };
    }

    if (a === "checkout") {
      if (b === "success") return { route: "checkout-success" };
      return { route: "checkout" };
    }

    if (a === "journal") {
      if (!b) return { route: "journal" };
      const post = (window.JOURNAL || []).find((p) => p.slug === b);
      if (!post) return { route: "journal" };
      return { route: "journal-post", currentPost: post };
    }

    if (a === "about") return { route: "about" };
    if (a === "contact") return { route: "contact" };
    return { route: "home" };
  }

  function buildPath(route, entity) {
    switch (route) {
      case "home":             return "/";
      case "catalog":          return "/experiences";
      case "detail":           return entity ? `/experiences/${entity.slug}` : "/experiences";
      case "checkout":         return "/checkout";
      case "checkout-success": return "/checkout/success";
      case "about":            return "/about";
      case "contact":          return "/contact";
      case "journal":          return "/journal";
      case "journal-post":     return entity ? `/journal/${entity.slug}` : "/journal";
      default:                 return "/";
    }
  }

  // Global navigate — wired by App on mount. Other modules call via window.__bbNavigate.
  function navigate(route, entity) {
    const fn = window.__bbNavigate;
    if (fn) fn(route, entity);
  }

  // Minimal Link component that renders a real <a href="..."> but intercepts left-click
  // to use pushState. Middle/cmd/ctrl/shift-click fall through to browser (new tab, etc).
  function Link({ to, route, entity, onClick, children, className, activeClassName, currentPath, ...rest }) {
    const href = to || buildPath(route, entity);
    const isActive = currentPath && href === currentPath;
    const cls = [className, isActive && activeClassName].filter(Boolean).join(" ");
    const handle = (e) => {
      if (onClick) onClick(e);
      if (e.defaultPrevented) return;
      if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;
      e.preventDefault();
      navigate(route, entity);
    };
    return React.createElement("a", { href, className: cls || undefined, onClick: handle, ...rest }, children);
  }

  // Per-route title. Keeps strings short — "<thing> — Bacalar Beyond".
  function titleFor(route, exp, post, lang) {
    const t = {
      en: {
        home: "Bacalar Beyond — Small-group expeditions of the Mayan Riviera",
        catalog: "Expeditions — " + SITE,
        detail: exp ? `${exp.title.en} · ${exp.location} — ${SITE}` : SITE,
        checkout: "Checkout — " + SITE,
        "checkout-success": "Reservation confirmed — " + SITE,
        about: "About — " + SITE,
        contact: "Contact — " + SITE,
        journal: "The Journal — " + SITE,
        "journal-post": post ? `${post.title.en} — ${SITE}` : SITE,
      },
      es: {
        home: "Bacalar Beyond — Expediciones de grupo pequeño en la Riviera Maya",
        catalog: "Expediciones — " + SITE,
        detail: exp ? `${exp.title.es} · ${exp.location} — ${SITE}` : SITE,
        checkout: "Pagar — " + SITE,
        "checkout-success": "Reserva confirmada — " + SITE,
        about: "Nosotros — " + SITE,
        contact: "Contacto — " + SITE,
        journal: "El Diario — " + SITE,
        "journal-post": post ? `${post.title.es} — ${SITE}` : SITE,
      },
    };
    return t[lang]?.[route] || t.en[route] || SITE;
  }

  // Per-route meta description. Search engines use this as snippet.
  function descFor(route, exp, post, lang) {
    const d = {
      en: {
        home: "Small-group sail, dive, ruin, and biosphere expeditions led by local Maya-descended guides on the Laguna de Bacalar, cenotes, and Yucatán Peninsula.",
        catalog: "Every Bacalar Beyond expedition in one place — twelve small-group journeys through the Mayan Riviera, by water, by jungle, by ruin.",
        detail: exp ? `${exp.subtitle.en} Led by a local Bacalar guide. ${exp.duration.en}, max ${exp.group.en.replace("Max ", "")}.` : "",
        checkout: "Review your Bacalar Beyond cart and reserve your expeditions. Paid in full at checkout, free cancellation up to 72h before departure.",
        "checkout-success": "Your Bacalar Beyond reservation is confirmed. Your guide will write to you the day before departure.",
        about: "Bacalar Beyond was founded by three Bacalar-raised locals. Small groups, local guides, 4% of every booking to the lagoon reserve.",
        contact: "Write to us from Bacalar. Custom itineraries, dock-side answers within 24 hours, usually from Itzel herself.",
        journal: "Field notes from the edge of the lagoon — essays on stromatolites, cenote etymology, pirate canals, and the rhythms of a six-o'clock kitchen.",
        "journal-post": post ? `${post.excerpt.en} A Bacalar Beyond field note.` : "",
      },
      es: {
        home: "Expediciones de grupo pequeño en vela, buceo, ruinas y biosfera con guías locales de ascendencia maya en la Laguna de Bacalar, cenotes y Península de Yucatán.",
        catalog: "Cada expedición de Bacalar Beyond en un solo lugar — doce viajes de grupo pequeño por la Riviera Maya, por agua, selva y ruinas.",
        detail: exp ? `${exp.subtitle.es} Con guía local de Bacalar. ${exp.duration.es}, máx ${exp.group.es.replace("Máx ", "")}.` : "",
        checkout: "Revisa tu carrito de Bacalar Beyond y reserva tus expediciones. Pago completo al reservar, cancelación gratis hasta 72h antes de la salida.",
        "checkout-success": "Tu reserva de Bacalar Beyond está confirmada. Tu guía te escribirá el día anterior.",
        about: "Bacalar Beyond fue fundada por tres bacaleños. Grupos pequeños, guías locales, 4% de cada reserva para la reserva de la laguna.",
        contact: "Escríbenos desde Bacalar. Itinerarios a medida, respuesta desde el muelle en menos de 24 horas, casi siempre de Itzel.",
        journal: "Notas de campo desde la orilla de la laguna — ensayos sobre estromatolitos, etimología de 'cenote', canales piratas y la cocina de las seis.",
        "journal-post": post ? `${post.excerpt.es} Una nota de campo de Bacalar Beyond.` : "",
      },
    };
    return d[lang]?.[route] || d.en[route] || "";
  }

  window.__bbRouter = { parseRoute, buildPath, navigate, Link, titleFor, descFor };
})();
