const menuToggle = document.querySelector("[data-menu-toggle]");
const mainNav = document.querySelector("[data-main-nav]");
const menuOverlay = document.querySelector("[data-menu-overlay]");
const navLinks = mainNav ? mainNav.querySelectorAll("a") : [];

if (menuToggle && mainNav) {
  const openClass = "is-open";
  const isCompactNav = () => window.innerWidth <= 980;

  const setMenuState = (isOpen) => {
    mainNav.classList.toggle(openClass, isOpen);
    if (menuOverlay) {
      menuOverlay.classList.toggle("is-open", isOpen);
    }
    menuToggle.setAttribute("aria-expanded", String(isOpen));
    document.body.classList.toggle("menu-open", isOpen);
    menuToggle.setAttribute(
      "aria-label",
      isOpen ? "Cerrar menú de navegación" : "Abrir menú de navegación"
    );
  };

  menuToggle.addEventListener("click", () => {
    const isOpen = mainNav.classList.contains(openClass);
    setMenuState(!isOpen);
  });

  navLinks.forEach((link) => {
    link.addEventListener("click", (event) => {
      if (!isCompactNav()) {
        setMenuState(false);
        return;
      }

      const destination = link.getAttribute("href");
      if (!destination) {
        setMenuState(false);
        return;
      }

      event.preventDefault();
      link.classList.add("is-pressed");

      window.setTimeout(() => {
        setMenuState(false);
        link.classList.remove("is-pressed");

        if (destination.startsWith("#")) {
          const targetNode = document.querySelector(destination);
          if (targetNode) {
            history.replaceState(null, "", destination);
            targetNode.scrollIntoView({ behavior: "smooth", block: "start" });
            return;
          }
        }

        window.location.href = destination;
      }, 170);
    });
  });

  if (menuOverlay) {
    menuOverlay.addEventListener("click", () => {
      setMenuState(false);
    });
  }

  document.addEventListener("keydown", (event) => {
    if (event.key === "Escape") {
      setMenuState(false);
    }
  });

  window.addEventListener("resize", () => {
    if (!isCompactNav()) {
      setMenuState(false);
    }
  });
}

const markMissingImage = (shell) => {
  if (!shell) {
    return;
  }
  shell.classList.add("is-missing");
};

const clearMissingImage = (shell) => {
  if (!shell) {
    return;
  }
  shell.classList.remove("is-missing");
};

const initMediaFallback = (root = document) => {
  const mediaShells = root.querySelectorAll(".media-shell");
  mediaShells.forEach((shell) => {
    const image = shell.querySelector("img");
    if (!image) {
      return;
    }

    if (!image.dataset.fallbackBound) {
      image.addEventListener("error", () => markMissingImage(shell));
      image.addEventListener("load", () => clearMissingImage(shell));
      image.dataset.fallbackBound = "true";
    }

    if (image.complete) {
      if (image.naturalWidth === 0) {
        markMissingImage(shell);
      } else {
        clearMissingImage(shell);
      }
    }
  });
};

initMediaFallback(document);

const yearNode = document.querySelector("[data-year]");
if (yearNode) {
  yearNode.textContent = new Date().getFullYear();
}

const escapeHTML = (value) =>
  String(value ?? "")
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#39;");

const MENU_V2_CATEGORY_ICONS = {
  tostadas: "tabler-bread",
  "titas-dulce-salado": "tabler-chef-hat",
  extras: "tabler-plus",
  bowls: "tabler-bowl-spoon",
  bagels: "tabler-cheese",
  batidos: "tabler-milkshake",
  smoothies: "tabler-cup",
  dulces: "tabler-cake",
  cafes: "tabler-coffee",
  "tortitas-gofres": "tabler-cookie",
  entrantes: "tabler-bowl",
  ensaladas: "tabler-salad",
  burgers: "tabler-burger",
  sandwich: "tabler-bread"
};

const getMenuV2CategoryIcon = (categoryId) =>
  MENU_V2_CATEGORY_ICONS[String(categoryId || "").toLowerCase()] || "tabler-chef-hat";

const initMenuTabs = (
  root = document,
  { initialKey = null, syncHash = true, updateHashOnInit = false } = {}
) => {
  const menuTabs = root.querySelectorAll("[data-menu-tab]");
  const menuPanels = root.querySelectorAll("[data-menu-panel]");
  if (!menuTabs.length || !menuPanels.length) {
    return false;
  }

  const panelByKey = new Map();
  const tabByKey = new Map();
  const keyByPanelId = new Map();

  menuPanels.forEach((panel) => {
    const key = panel.getAttribute("data-menu-panel");
    if (!key) {
      return;
    }
    panelByKey.set(key, panel);
    if (panel.id) {
      keyByPanelId.set(panel.id, key);
    }
  });

  menuTabs.forEach((tab) => {
    const key = tab.getAttribute("data-menu-tab");
    if (key) {
      tabByKey.set(key, tab);
    }
  });

  const activateMenuTab = (key, shouldSyncHash = true) => {
    if (!panelByKey.has(key) || !tabByKey.has(key)) {
      return;
    }

    menuTabs.forEach((tab) => {
      const isActive = tab.getAttribute("data-menu-tab") === key;
      tab.classList.toggle("is-active", isActive);
      tab.setAttribute("aria-selected", String(isActive));
      tab.setAttribute("tabindex", isActive ? "0" : "-1");
    });

    menuPanels.forEach((panel) => {
      const isActive = panel.getAttribute("data-menu-panel") === key;
      panel.classList.toggle("is-active", isActive);
      panel.hidden = !isActive;
    });

    if (!syncHash || !shouldSyncHash) {
      return;
    }

    const activePanel = panelByKey.get(key);
    if (activePanel && activePanel.id) {
      history.replaceState(null, "", `#${activePanel.id}`);
    }
  };

  menuTabs.forEach((tab) => {
    tab.addEventListener("click", () => {
      const key = tab.getAttribute("data-menu-tab");
      if (key) {
        activateMenuTab(key, true);
      }
    });
  });

  const activateFromHash = () => {
    const rawHash = window.location.hash.replace("#", "");
    const keyFromHash = keyByPanelId.get(rawHash);
    if (keyFromHash) {
      activateMenuTab(keyFromHash, false);
    }
  };

  const activeTab = root.querySelector("[data-menu-tab].is-active");
  const fallbackKey = activeTab ? activeTab.getAttribute("data-menu-tab") : null;
  const firstKey = menuTabs[0]?.getAttribute("data-menu-tab") || null;
  const resolvedInitialKey = initialKey || fallbackKey || firstKey;

  if (resolvedInitialKey) {
    activateMenuTab(resolvedInitialKey, updateHashOnInit);
  }

  if (syncHash) {
    activateFromHash();
    window.addEventListener("hashchange", activateFromHash);
  }

  return true;
};

const getMenuDockAnchorOffset = (dock, panel) => {
  if (!dock) {
    return 0;
  }
  const topValue = Number.parseFloat(window.getComputedStyle(dock).top || "0");
  const topOffset = Number.isFinite(topValue) ? topValue : 0;
  let dockHeight = dock.getBoundingClientRect().height;
  const groupsPanel = panel || dock.querySelector("[data-menu-dock-panel]");
  const isExpanded = groupsPanel && !dock.classList.contains("is-collapsed");

  if (isExpanded && groupsPanel) {
    const currentPanelHeight = groupsPanel.getBoundingClientRect().height;
    const fullPanelHeight = groupsPanel.scrollHeight;
    if (fullPanelHeight > currentPanelHeight + 1) {
      dockHeight += fullPanelHeight - currentPanelHeight;
    }
  }

  const visualGap = 14;
  return Math.max(0, Math.ceil(dockHeight + topOffset + visualGap));
};

const initMenuDock = (root = document) => {
  const dock = root.querySelector("[data-menu-dock]");
  if (!dock) {
    return null;
  }

  const toggle = dock.querySelector("[data-menu-dock-toggle]");
  const panel = dock.querySelector("[data-menu-dock-panel]");
  if (!toggle || !panel) {
    return null;
  }
  const toggleLabel = toggle.querySelector("[data-menu-dock-toggle-label]");
  const rootElement = root instanceof Element ? root : document.documentElement;

  const updateDockOffset = () => {
    const offset = getMenuDockAnchorOffset(dock, panel);
    rootElement.style.setProperty("--menu-dock-offset", `${offset}px`);
  };

  const setCollapsed = (collapsed) => {
    dock.classList.toggle("is-collapsed", collapsed);
    panel.setAttribute("aria-hidden", String(collapsed));
    toggle.setAttribute("aria-expanded", String(!collapsed));
    toggle.setAttribute(
      "aria-label",
      collapsed ? "Desplegar menú de categorías" : "Plegar menú de categorías"
    );
    if (toggleLabel) {
      toggleLabel.textContent = collapsed ? "Desplegar menú" : "Plegar menú";
    }
    window.requestAnimationFrame(updateDockOffset);
  };

  setCollapsed(false);

  let resizeTicking = false;
  const handleResize = () => {
    if (resizeTicking) {
      return;
    }
    resizeTicking = true;
    window.requestAnimationFrame(() => {
      updateDockOffset();
      resizeTicking = false;
    });
  };

  const collapseOnScrollIntent = () => {
    if (!dock.classList.contains("is-collapsed")) {
      setCollapsed(true);
    }
  };

  const onKeyScrollIntent = (event) => {
    const scrollKeys = new Set([
      "ArrowDown",
      "ArrowUp",
      "PageDown",
      "PageUp",
      "Home",
      "End",
      " ",
      "Spacebar"
    ]);
    if (scrollKeys.has(event.key)) {
      collapseOnScrollIntent();
    }
  };

  toggle.addEventListener("click", () => {
    const isCollapsed = dock.classList.contains("is-collapsed");
    setCollapsed(!isCollapsed);
  });

  dock.addEventListener("transitionend", (event) => {
    if (event.target === panel || event.propertyName === "max-height") {
      updateDockOffset();
    }
  });

  window.addEventListener("resize", handleResize);
  window.addEventListener("wheel", collapseOnScrollIntent, { passive: true });
  window.addEventListener("touchmove", collapseOnScrollIntent, { passive: true });
  window.addEventListener("keydown", onKeyScrollIntent);

  window.requestAnimationFrame(updateDockOffset);
  return { setCollapsed, updateDockOffset };
};

const initMenuFeedNavigation = (root = document, { initialKey = null } = {}) => {
  const menuButtons = Array.from(root.querySelectorAll("[data-menu-tab]"));
  const menuPanels = Array.from(root.querySelectorAll("[data-menu-panel]"));
  if (!menuButtons.length || !menuPanels.length) {
    return false;
  }

  const buttonByKey = new Map();
  const panelByKey = new Map();
  const keyByPanelId = new Map();

  menuButtons.forEach((button) => {
    const key = button.getAttribute("data-menu-tab");
    if (!key) {
      return;
    }
    buttonByKey.set(key, button);
    button.setAttribute("aria-current", "false");
    button.setAttribute("aria-pressed", "false");
  });

  menuPanels.forEach((panel) => {
    const key = panel.getAttribute("data-menu-panel");
    if (!key) {
      return;
    }
    panelByKey.set(key, panel);
    if (panel.id) {
      keyByPanelId.set(panel.id, key);
    }
    panel.hidden = false;
    panel.classList.add("is-pending-reveal");
  });

  let activeKey = null;

  const setActiveButton = (key) => {
    if (!buttonByKey.has(key) || activeKey === key) {
      return;
    }

    activeKey = key;
    menuButtons.forEach((button) => {
      const isActive = button.getAttribute("data-menu-tab") === key;
      button.classList.toggle("is-active", isActive);
      button.setAttribute("aria-current", isActive ? "true" : "false");
      button.setAttribute("aria-pressed", isActive ? "true" : "false");
    });
  };

  const getCurrentDockOffset = () => {
    const dock = root.querySelector("[data-menu-dock]");
    if (!dock) {
      return 0;
    }
    const panel = dock.querySelector("[data-menu-dock-panel]");
    return getMenuDockAnchorOffset(dock, panel);
  };

  const scrollToCategory = (key, behavior = "smooth") => {
    const panel = panelByKey.get(key);
    if (!panel) {
      return;
    }
    setActiveButton(key);
    const dockOffset = getCurrentDockOffset();
    const panelTop = panel.getBoundingClientRect().top + window.scrollY;
    const targetTop = Math.max(0, panelTop - dockOffset);
    window.scrollTo({ top: targetTop, behavior });
    if (panel.id) {
      history.replaceState(null, "", `#${panel.id}`);
    }
  };

  const resolveKeyFromHash = () => {
    const rawHash = window.location.hash.replace("#", "");
    return keyByPanelId.get(rawHash) || null;
  };

  menuButtons.forEach((button) => {
    button.addEventListener("click", () => {
      const key = button.getAttribute("data-menu-tab");
      if (key) {
        scrollToCategory(key, "smooth");
      }
    });
  });

  const revealObserver = new IntersectionObserver(
    (entries, observer) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) {
          return;
        }
        entry.target.classList.add("is-revealed");
        entry.target.classList.remove("is-pending-reveal");
        observer.unobserve(entry.target);
      });
    },
    {
      threshold: 0.18,
      rootMargin: "0px 0px -10% 0px"
    }
  );

  menuPanels.forEach((panel) => revealObserver.observe(panel));

  const updateActiveFromViewport = () => {
    const viewportAnchor = Math.min(240, window.innerHeight * 0.34);
    let nextActiveKey = activeKey || initialKey || menuButtons[0]?.getAttribute("data-menu-tab");
    let bestScore = Number.POSITIVE_INFINITY;

    menuPanels.forEach((panel) => {
      const key = panel.getAttribute("data-menu-panel");
      if (!key) {
        return;
      }
      const rect = panel.getBoundingClientRect();
      const isNearViewport = rect.bottom > viewportAnchor * 0.45 && rect.top < window.innerHeight * 0.88;
      if (!isNearViewport) {
        return;
      }
      const score = Math.abs(rect.top - viewportAnchor);
      if (score < bestScore) {
        bestScore = score;
        nextActiveKey = key;
      }
    });

    if (nextActiveKey) {
      setActiveButton(nextActiveKey);
    }
  };

  let scrollTicking = false;
  const handleScroll = () => {
    if (scrollTicking) {
      return;
    }
    scrollTicking = true;
    window.requestAnimationFrame(() => {
      updateActiveFromViewport();
      scrollTicking = false;
    });
  };

  window.addEventListener("scroll", handleScroll, { passive: true });
  window.addEventListener("resize", handleScroll);

  window.addEventListener("hashchange", () => {
    const keyFromHash = resolveKeyFromHash();
    if (keyFromHash) {
      scrollToCategory(keyFromHash, "smooth");
    }
  });

  const keyFromHash = resolveKeyFromHash();
  const firstKey = menuButtons[0]?.getAttribute("data-menu-tab") || null;
  const resolvedInitialKey = keyFromHash || initialKey || firstKey;

  if (resolvedInitialKey) {
    setActiveButton(resolvedInitialKey);
  }

  if (keyFromHash) {
    window.requestAnimationFrame(() => {
      scrollToCategory(keyFromHash, "auto");
    });
  } else {
    window.requestAnimationFrame(updateActiveFromViewport);
  }

  return true;
};

const renderPublicMenuFromStore = async () => {
  const menuPage = document.querySelector(".menu-page-v2:not(.menu-admin-page)");
  if (!menuPage || !window.MenuStore) {
    return false;
  }

  const tabsMount = menuPage.querySelector("[data-menu-tabs]");
  const panelsMount = menuPage.querySelector("[data-menu-panels]");
  if (!tabsMount || !panelsMount) {
    return false;
  }

  let data = null;
  try {
    data = await window.MenuStore.loadData();
  } catch (error) {
    data = window.MenuStore.getDefaultData();
  }

  if (!data.categories?.length) {
    return false;
  }

  const eyebrowNode = menuPage.querySelector("[data-menu-brand-eyebrow]");
  const titleNode = menuPage.querySelector("[data-menu-brand-title]");
  const descriptionNode = menuPage.querySelector("[data-menu-brand-description]");

  if (eyebrowNode) eyebrowNode.textContent = "CARTA";
  if (titleNode) titleNode.textContent = data.brand.title;
  if (descriptionNode) {
    const description = String(data.brand.description || "").trim();
    descriptionNode.textContent = description;
    descriptionNode.hidden = !description.length;
  }

  tabsMount.innerHTML = data.categories
    .map(
      (category) => {
        const icon = getMenuV2CategoryIcon(category.id);
        return `
      <button
        id="tab-${escapeHTML(category.id)}"
        class="menu-v2-tab"
        type="button"
        aria-controls="menu-${escapeHTML(category.id)}"
        data-menu-tab="${escapeHTML(category.id)}"
      >
        <svg class="menu-v2-tab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <use href="#${escapeHTML(icon)}" xlink:href="#${escapeHTML(icon)}"></use>
        </svg>
        <span class="menu-v2-tab-label">${escapeHTML(category.label)}</span>
      </button>
    `;
      }
    )
    .join("");

  panelsMount.innerHTML = data.categories
    .map((category) => {
      const itemsHTML = category.items
        .map((item) => {
          const featuredClass = item.featured ? " menu-v2-product-featured" : "";
          const badge = String(item.badge || "").trim();
          const badgeHTML = badge ? `<span>${escapeHTML(badge)}</span>` : "";
          return `
          <article class="menu-v2-product${featuredClass}">
            <figure class="menu-v2-product-media media-shell" data-fallback="${escapeHTML(item.name)}">
              <img src="${escapeHTML(item.image)}" alt="${escapeHTML(item.alt)}">
            </figure>
            <div class="menu-v2-product-copy">
              <p class="menu-v2-kicker">${escapeHTML(item.tag)}</p>
              <h3>${escapeHTML(item.name)}</h3>
              <p>${escapeHTML(item.description)}</p>
              <div class="menu-v2-meta">
                <strong>${escapeHTML(item.price)}</strong>
                ${badgeHTML}
              </div>
            </div>
          </article>
        `;
        })
        .join("");

      return `
      <article
        id="menu-${escapeHTML(category.id)}"
        class="menu-v2-panel"
        role="region"
        aria-labelledby="tab-${escapeHTML(category.id)}"
        data-menu-panel="${escapeHTML(category.id)}"
      >
        <header class="menu-v2-panel-head">
          <h2>${escapeHTML(category.label)}</h2>
          <p>${escapeHTML(category.description)}</p>
        </header>
        <div class="menu-v2-grid">
          ${itemsHTML}
        </div>
      </article>
    `;
    })
    .join("");

  initMediaFallback(menuPage);

  const hashId = window.location.hash.replace("#", "");
  const hashCategoryId = hashId.startsWith("menu-") ? hashId.slice(5) : "";
  const hasHashCategory = data.categories.some((category) => category.id === hashCategoryId);
  const initialKey = hasHashCategory
    ? hashCategoryId
    : data.defaultCategoryId || data.categories[0].id;

  initMenuDock(menuPage);
  initMenuFeedNavigation(menuPage, { initialKey });

  return true;
};

const renderMenuListFromStore = async () => {
  const menuPage = document.querySelector(".menu-page-lista:not(.menu-admin-page)");
  if (!menuPage || !window.MenuStore) {
    return false;
  }

  const tabsMount = menuPage.querySelector("[data-menu-tabs]");
  const panelsMount = menuPage.querySelector("[data-menu-panels]");
  if (!tabsMount || !panelsMount) {
    return false;
  }

  let data = null;
  try {
    data = await window.MenuStore.loadData();
  } catch (error) {
    data = window.MenuStore.getDefaultData();
  }

  if (!data.categories?.length) {
    return false;
  }

  const eyebrowNode = menuPage.querySelector("[data-menu-brand-eyebrow]");
  const titleNode = menuPage.querySelector("[data-menu-brand-title]");
  const descriptionNode = menuPage.querySelector("[data-menu-brand-description]");

  if (eyebrowNode) eyebrowNode.textContent = "CARTA EXPRESS";
  if (titleNode) titleNode.textContent = "Tu carta en formato rápido";
  if (descriptionNode) {
    const description = "Selecciona categoría y revisa productos en una vista directa, pensada para móvil.";
    descriptionNode.textContent = description;
    descriptionNode.hidden = !description.length;
  }

  tabsMount.innerHTML = data.categories
    .map(
      (category) => `
      <button
        id="lista-tab-${escapeHTML(category.id)}"
        class="menu-lista-tab"
        type="button"
        role="tab"
        aria-selected="false"
        aria-controls="lista-${escapeHTML(category.id)}"
        data-menu-tab="${escapeHTML(category.id)}"
      >${escapeHTML(category.label)}</button>
    `
    )
    .join("");

  panelsMount.innerHTML = data.categories
    .map((category) => {
      const itemsHTML = category.items
        .map((item) => {
          const badge = String(item.badge || "").trim();
          const badgeHTML = badge ? `<span>${escapeHTML(badge)}</span>` : "";
          return `
          <article class="menu-lista-item">
            <div class="menu-lista-price" aria-label="Precio">${escapeHTML(item.price)}</div>
            <div class="menu-lista-copy">
              <h3>${escapeHTML(item.name)}</h3>
              <p>${escapeHTML(item.description)}</p>
              ${badgeHTML}
            </div>
          </article>
        `
        })
        .join("");

      return `
      <article
        id="lista-${escapeHTML(category.id)}"
        class="menu-lista-panel"
        role="tabpanel"
        aria-labelledby="lista-tab-${escapeHTML(category.id)}"
        data-menu-panel="${escapeHTML(category.id)}"
        hidden
      >
        <header class="menu-lista-panel-head">
          <h2>${escapeHTML(category.label)}</h2>
          <p>${escapeHTML(category.description)}</p>
        </header>
        <div class="menu-lista-items">
          ${itemsHTML}
        </div>
      </article>
    `;
    })
    .join("");

  const hashId = window.location.hash.replace("#", "");
  const hashCategoryId = hashId.startsWith("lista-") ? hashId.slice(6) : "";
  const hasHashCategory = data.categories.some((category) => category.id === hashCategoryId);
  const initialKey = hasHashCategory
    ? hashCategoryId
    : data.defaultCategoryId || data.categories[0].id;

  initMenuTabs(menuPage, {
    initialKey,
    syncHash: true,
    updateHashOnInit: false
  });

  return true;
};

const renderHomeEssentialsFromStore = async () => {
  const essentialsSection = document.querySelector(".essentials");
  const essentialsGrid = document.querySelector(".essentials .product-grid");
  if (!essentialsGrid || !window.MenuStore) {
    return false;
  }

  if (essentialsSection) {
    essentialsSection.hidden = true;
  }
  essentialsGrid.innerHTML = "";

  let data = null;
  try {
    data = await window.MenuStore.loadData();
  } catch (error) {
    data = window.MenuStore.getDefaultData();
  }

  const essentials = [];
  data.categories.forEach((category) => {
    category.items.forEach((item) => {
      if (!item) {
        return;
      }
      if (item.essential) {
        essentials.push({
          ...item,
          categoryLabel: category.label
        });
      }
    });
  });

  const selected = [];
  const seenIds = new Set();

  const addItems = (items) => {
    items.forEach((item) => {
      if (selected.length >= 4) {
        return;
      }
      const key = String(item.id || `${item.name}-${item.price}`).trim();
      if (seenIds.has(key)) {
        return;
      }
      seenIds.add(key);
      selected.push(item);
    });
  };

  addItems(essentials);

  if (!selected.length) {
    return true;
  }

  essentialsGrid.innerHTML = selected
    .map(
      (item) => `
        <article class="product-card">
          <span class="tag">Imprescindible</span>
          <figure class="media-shell" data-fallback="${escapeHTML(item.name)}">
            <img src="${escapeHTML(item.image)}" alt="${escapeHTML(item.alt || item.name)}">
          </figure>
          <div class="card-body">
            <h3>${escapeHTML(item.name)}</h3>
            <p>${escapeHTML(item.description)}</p>
            <p class="price">${escapeHTML(item.price)}</p>
          </div>
        </article>
      `
    )
    .join("");

  if (essentialsSection) {
    essentialsSection.hidden = false;
  }

  initMediaFallback(essentialsGrid);
  return true;
};

const renderHomeCategoryImagesFromStore = async () => {
  const categoryImages = Array.from(document.querySelectorAll("[data-home-category-image]"));
  if (!categoryImages.length || !window.MenuStore) {
    return false;
  }

  let data = null;
  try {
    data = await window.MenuStore.loadData();
  } catch (error) {
    data = window.MenuStore.getDefaultData();
  }

  const categoriesById = new Map(
    (Array.isArray(data.categories) ? data.categories : []).map((category) => [category.id, category])
  );

  const shuffle = (items) => {
    const next = [...items];
    for (let index = next.length - 1; index > 0; index -= 1) {
      const swapIndex = Math.floor(Math.random() * (index + 1));
      [next[index], next[swapIndex]] = [next[swapIndex], next[index]];
    }
    return next;
  };

  const pickFirstLoadableItem = async (items) => {
    const queue = shuffle(items);

    for (const item of queue) {
      const source = String(item?.image || "").trim();
      if (!source) {
        continue;
      }

      const loadOk = await new Promise((resolve) => {
        const probe = new Image();
        probe.onload = () => resolve(true);
        probe.onerror = () => resolve(false);
        probe.src = source;
      });

      if (loadOk) {
        return item;
      }
    }

    return null;
  };

  for (const imageNode of categoryImages) {
    const categoryId = imageNode.getAttribute("data-home-category-image");
    if (!categoryId) {
      continue;
    }

    const category = categoriesById.get(categoryId);
    if (!category?.items?.length) {
      continue;
    }

    const candidates = category.items.filter((item) => {
      const src = String(item?.image || "").trim();
      return src.length > 0;
    });
    if (!candidates.length) {
      continue;
    }

    const selected = await pickFirstLoadableItem(candidates);
    if (!selected) {
      continue;
    }

    const shell = imageNode.closest(".media-shell");
    imageNode.src = selected.image;
    imageNode.alt = String(selected.alt || selected.name || imageNode.alt || "").trim();
    clearMissingImage(shell);
  }

  const categoriesSection = document.querySelector(".categories");
  if (categoriesSection) {
    initMediaFallback(categoriesSection);
  }

  return true;
};

void (async () => {
  const wasMenuRendered = await renderPublicMenuFromStore();
  const wasListRendered = wasMenuRendered ? false : await renderMenuListFromStore();
  await renderHomeCategoryImagesFromStore();
  await renderHomeEssentialsFromStore();
  if (!wasMenuRendered && !wasListRendered) {
    initMenuTabs(document, { syncHash: true });
  }
})();
